57 #define cimg_version 152
88 #if defined(unix) || defined(__unix) || defined(__unix__) \
89 || defined(linux) || defined(__linux) || defined(__linux__) \
90 || defined(sun) || defined(__sun) \
91 || defined(BSD) || defined(__OpenBSD__) || defined(__NetBSD__) \
92 || defined(__FreeBSD__) || defined __DragonFly__ \
93 || defined(sgi) || defined(__sgi) \
94 || defined(__MACOSX__) || defined(__APPLE__) \
95 || defined(__CYGWIN__)
97 #elif defined(_MSC_VER) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) \
98 || defined(WIN64) || defined(_WIN64) || defined(__WIN64__)
103 #elif !(cimg_OS==0 || cimg_OS==1 || cimg_OS==2)
104 #error CImg Library: Invalid configuration variable 'cimg_OS'.
105 #error (correct values are '0 = unknown OS', '1 = Unix-like OS', '2 = Microsoft Windows').
110 #pragma warning(push)
111 #pragma warning(disable:4311)
112 #pragma warning(disable:4312)
113 #pragma warning(disable:4800)
114 #pragma warning(disable:4804)
115 #pragma warning(disable:4996)
116 #define _CRT_SECURE_NO_DEPRECATE 1
117 #define _CRT_NONSTDC_NO_DEPRECATE 1
122 #include <sys/types.h>
123 #include <sys/time.h>
131 #define _WIN32_IE 0x0400
136 #define cimg_snprintf _snprintf
137 #define cimg_vsnprintf _vsnprintf
139 #ifndef cimg_snprintf
141 #define cimg_snprintf snprintf
142 #define cimg_vsnprintf vsnprintf
148 #ifndef cimg_file_separator
150 #define cimg_file_separator '\\'
152 #define cimg_file_separator '/'
167 #ifndef cimg_verbosity
168 #define cimg_verbosity 2
169 #elif !(cimg_verbosity==0 || cimg_verbosity==1 || cimg_verbosity==2 || cimg_verbosity==3 || cimg_verbosity==4)
170 #error CImg Library: Configuration variable 'cimg_verbosity' is badly defined.
171 #error (should be { 0=quiet | 1=console | 2=dialog | 3=console+warnings | 4=dialog+warnings }).
181 #define cimg_display 0
183 #if defined(__MACOSX__) || defined(__APPLE__)
184 #define cimg_display 1
186 #define cimg_display 1
189 #define cimg_display 2
191 #elif !(cimg_display==0 || cimg_display==1 || cimg_display==2)
192 #error CImg Library: Configuration variable 'cimg_display' is badly defined.
193 #error (should be { 0=none | 1=X-Window (X11) | 2=Microsoft GDI32 }).
198 #include <X11/Xlib.h>
199 #include <X11/Xutil.h>
200 #include <X11/keysym.h>
205 #include <X11/extensions/XShm.h>
207 #ifdef cimg_use_xrandr
208 #include <X11/extensions/Xrandr.h>
212 #define cimg_appname "CImg"
222 #ifdef cimg_use_openmp
226 #define _cimg_static static
236 #ifdef cimg_use_opencv
239 #define _cimg_redefine_True
243 #define _cimg_redefine_False
297 #ifdef cimg_use_minc2
298 #include "minc_io_simple_volume.h"
299 #include "minc_1_simple.h"
300 #include "minc_1_simple_rw.h"
311 #ifdef cimg_use_ffmpeg
312 #if (defined(_STDINT_H) || defined(_STDINT_H_)) && !defined(UINT64_C)
313 #warning "__STDC_CONSTANT_MACROS has to be defined before including <stdint.h>, this file will probably not compile."
315 #ifndef __STDC_CONSTANT_MACROS
316 #define __STDC_CONSTANT_MACROS // ...or stdint.h wont' define UINT64_C, needed by libavutil
319 #include "avformat.h"
345 #ifdef cimg_use_magick
346 #include "Magick++.h"
357 #ifdef cimg_use_fftw3
371 #ifdef cimg_use_board
374 #define _cimg_redefine_None
386 #ifdef cimg_use_openexr
387 #include "ImfRgbaFile.h"
388 #include "ImfInputFile.h"
389 #include "ImfChannelList.h"
390 #include "ImfMatrixAttribute.h"
391 #include "ImfArray.h"
401 #ifdef cimg_use_lapack
403 extern void sgetrf_(
int*,
int*,
float*,
int*,
int*,
int*);
404 extern void sgetri_(
int*,
float*,
int*,
int*,
float*,
int*,
int*);
405 extern void sgetrs_(
char*,
int*,
int*,
float*,
int*,
int*,
float*,
int*,
int*);
406 extern void sgesvd_(
char*,
char*,
int*,
int*,
float*,
int*,
float*,
float*,
int*,
float*,
int*,
float*,
int*,
int*);
407 extern void ssyev_(
char*,
char*,
int*,
float*,
int*,
float*,
float*,
int*,
int*);
408 extern void dgetrf_(
int*,
int*,
double*,
int*,
int*,
int*);
409 extern void dgetri_(
int*,
double*,
int*,
int*,
double*,
int*,
int*);
410 extern void dgetrs_(
char*,
int*,
int*,
double*,
int*,
int*,
double*,
int*,
int*);
411 extern void dgesvd_(
char*,
char*,
int*,
int*,
double*,
int*,
double*,
double*,
int*,
double*,
int*,
double*,
int*,
int*);
412 extern void dsyev_(
char*,
char*,
int*,
double*,
int*,
double*,
double*,
int*,
int*);
413 extern void dgels_(
char*,
int*,
int*,
int*,
double*,
int*,
double*,
int*,
double*,
int*,
int*);
414 extern void sgels_(
char*,
int*,
int*,
int*,
float*,
int*,
float*,
int*,
float*,
int*,
int*);
426 #define _cimg_redefine_min
430 #define _cimg_redefine_max
434 #define _cimg_redefine_PI
441 #ifdef cimg_namespace_suffix
442 #define __cimg_library_suffixed(s) cimg_library_##s
443 #define _cimg_library_suffixed(s) __cimg_library_suffixed(s)
444 #define cimg_library_suffixed _cimg_library_suffixed(cimg_namespace_suffix)
446 #define cimg_library_suffixed cimg_library
459 #define cimg_usage(usage) cimg_library_suffixed::cimg::option((char*)0,argc,argv,(char*)0,usage,false)
460 #define cimg_help(str) cimg_library_suffixed::cimg::option((char*)0,argc,argv,str,(char*)0)
461 #define cimg_option(name,defaut,usage) cimg_library_suffixed::cimg::option(name,argc,argv,defaut,usage)
462 #define cimg_argument(pos) cimg_library_suffixed::cimg::argument(pos,argc,argv)
463 #define cimg_argument1(pos,s0) cimg_library_suffixed::cimg::argument(pos,argc,argv,1,s0)
464 #define cimg_argument2(pos,s0,s1) cimg_library_suffixed::cimg::argument(pos,argc,argv,2,s0,s1)
465 #define cimg_argument3(pos,s0,s1,s2) cimg_library_suffixed::cimg::argument(pos,argc,argv,3,s0,s1,s2)
466 #define cimg_argument4(pos,s0,s1,s2,s3) cimg_library_suffixed::cimg::argument(pos,argc,argv,4,s0,s1,s2,s3)
467 #define cimg_argument5(pos,s0,s1,s2,s3,s4) cimg_library_suffixed::cimg::argument(pos,argc,argv,5,s0,s1,s2,s3,s4)
468 #define cimg_argument6(pos,s0,s1,s2,s3,s4,s5) cimg_library_suffixed::cimg::argument(pos,argc,argv,6,s0,s1,s2,s3,s4,s5)
469 #define cimg_argument7(pos,s0,s1,s2,s3,s4,s5,s6) cimg_library_suffixed::cimg::argument(pos,argc,argv,7,s0,s1,s2,s3,s4,s5,s6)
470 #define cimg_argument8(pos,s0,s1,s2,s3,s4,s5,s6,s7) cimg_library_suffixed::cimg::argument(pos,argc,argv,8,s0,s1,s2,s3,s4,s5,s6,s7)
471 #define cimg_argument9(pos,s0,s1,s2,s3,s4,s5,s6,s7,s8) cimg_library_suffixed::cimg::argument(pos,argc,argv,9,s0,s1,s2,s3,s4,s5,s6,s7,s8)
474 #define CImg_2x2(I,T) T I[4]; \
475 T& I##cc = I[0]; T& I##nc = I[1]; \
476 T& I##cn = I[2]; T& I##nn = I[3]; \
480 #define CImg_3x3(I,T) T I[9]; \
481 T& I##pp = I[0]; T& I##cp = I[1]; T& I##np = I[2]; \
482 T& I##pc = I[3]; T& I##cc = I[4]; T& I##nc = I[5]; \
483 T& I##pn = I[6]; T& I##cn = I[7]; T& I##nn = I[8]; \
484 I##pp = I##cp = I##np = \
485 I##pc = I##cc = I##nc = \
486 I##pn = I##cn = I##nn = 0
488 #define CImg_4x4(I,T) T I[16]; \
489 T& I##pp = I[0]; T& I##cp = I[1]; T& I##np = I[2]; T& I##ap = I[3]; \
490 T& I##pc = I[4]; T& I##cc = I[5]; T& I##nc = I[6]; T& I##ac = I[7]; \
491 T& I##pn = I[8]; T& I##cn = I[9]; T& I##nn = I[10]; T& I##an = I[11]; \
492 T& I##pa = I[12]; T& I##ca = I[13]; T& I##na = I[14]; T& I##aa = I[15]; \
493 I##pp = I##cp = I##np = I##ap = \
494 I##pc = I##cc = I##nc = I##ac = \
495 I##pn = I##cn = I##nn = I##an = \
496 I##pa = I##ca = I##na = I##aa = 0
498 #define CImg_5x5(I,T) T I[25]; \
499 T& I##bb = I[0]; T& I##pb = I[1]; T& I##cb = I[2]; T& I##nb = I[3]; T& I##ab = I[4]; \
500 T& I##bp = I[5]; T& I##pp = I[6]; T& I##cp = I[7]; T& I##np = I[8]; T& I##ap = I[9]; \
501 T& I##bc = I[10]; T& I##pc = I[11]; T& I##cc = I[12]; T& I##nc = I[13]; T& I##ac = I[14]; \
502 T& I##bn = I[15]; T& I##pn = I[16]; T& I##cn = I[17]; T& I##nn = I[18]; T& I##an = I[19]; \
503 T& I##ba = I[20]; T& I##pa = I[21]; T& I##ca = I[22]; T& I##na = I[23]; T& I##aa = I[24]; \
504 I##bb = I##pb = I##cb = I##nb = I##ab = \
505 I##bp = I##pp = I##cp = I##np = I##ap = \
506 I##bc = I##pc = I##cc = I##nc = I##ac = \
507 I##bn = I##pn = I##cn = I##nn = I##an = \
508 I##ba = I##pa = I##ca = I##na = I##aa = 0
510 #define CImg_2x2x2(I,T) T I[8]; \
511 T& I##ccc = I[0]; T& I##ncc = I[1]; \
512 T& I##cnc = I[2]; T& I##nnc = I[3]; \
513 T& I##ccn = I[4]; T& I##ncn = I[5]; \
514 T& I##cnn = I[6]; T& I##nnn = I[7]; \
520 #define CImg_3x3x3(I,T) T I[27]; \
521 T& I##ppp = I[0]; T& I##cpp = I[1]; T& I##npp = I[2]; \
522 T& I##pcp = I[3]; T& I##ccp = I[4]; T& I##ncp = I[5]; \
523 T& I##pnp = I[6]; T& I##cnp = I[7]; T& I##nnp = I[8]; \
524 T& I##ppc = I[9]; T& I##cpc = I[10]; T& I##npc = I[11]; \
525 T& I##pcc = I[12]; T& I##ccc = I[13]; T& I##ncc = I[14]; \
526 T& I##pnc = I[15]; T& I##cnc = I[16]; T& I##nnc = I[17]; \
527 T& I##ppn = I[18]; T& I##cpn = I[19]; T& I##npn = I[20]; \
528 T& I##pcn = I[21]; T& I##ccn = I[22]; T& I##ncn = I[23]; \
529 T& I##pnn = I[24]; T& I##cnn = I[25]; T& I##nnn = I[26]; \
530 I##ppp = I##cpp = I##npp = \
531 I##pcp = I##ccp = I##ncp = \
532 I##pnp = I##cnp = I##nnp = \
533 I##ppc = I##cpc = I##npc = \
534 I##pcc = I##ccc = I##ncc = \
535 I##pnc = I##cnc = I##nnc = \
536 I##ppn = I##cpn = I##npn = \
537 I##pcn = I##ccn = I##ncn = \
538 I##pnn = I##cnn = I##nnn = 0
540 #define cimg_get2x2(img,x,y,z,c,I,T) \
541 I[0] = (T)(img)(x,y,z,c), I[1] = (T)(img)(_n1##x,y,z,c), I[2] = (T)(img)(x,_n1##y,z,c), I[3] = (T)(img)(_n1##x,_n1##y,z,c)
543 #define cimg_get3x3(img,x,y,z,c,I,T) \
544 I[0] = (T)(img)(_p1##x,_p1##y,z,c), I[1] = (T)(img)(x,_p1##y,z,c), I[2] = (T)(img)(_n1##x,_p1##y,z,c), I[3] = (T)(img)(_p1##x,y,z,c), \
545 I[4] = (T)(img)(x,y,z,c), I[5] = (T)(img)(_n1##x,y,z,c), I[6] = (T)(img)(_p1##x,_n1##y,z,c), I[7] = (T)(img)(x,_n1##y,z,c), \
546 I[8] = (T)(img)(_n1##x,_n1##y,z,c)
548 #define cimg_get4x4(img,x,y,z,c,I,T) \
549 I[0] = (T)(img)(_p1##x,_p1##y,z,c), I[1] = (T)(img)(x,_p1##y,z,c), I[2] = (T)(img)(_n1##x,_p1##y,z,c), I[3] = (T)(img)(_n2##x,_p1##y,z,c), \
550 I[4] = (T)(img)(_p1##x,y,z,c), I[5] = (T)(img)(x,y,z,c), I[6] = (T)(img)(_n1##x,y,z,c), I[7] = (T)(img)(_n2##x,y,z,c), \
551 I[8] = (T)(img)(_p1##x,_n1##y,z,c), I[9] = (T)(img)(x,_n1##y,z,c), I[10] = (T)(img)(_n1##x,_n1##y,z,c), I[11] = (T)(img)(_n2##x,_n1##y,z,c), \
552 I[12] = (T)(img)(_p1##x,_n2##y,z,c), I[13] = (T)(img)(x,_n2##y,z,c), I[14] = (T)(img)(_n1##x,_n2##y,z,c), I[15] = (T)(img)(_n2##x,_n2##y,z,c)
554 #define cimg_get5x5(img,x,y,z,c,I,T) \
555 I[0] = (T)(img)(_p2##x,_p2##y,z,c), I[1] = (T)(img)(_p1##x,_p2##y,z,c), I[2] = (T)(img)(x,_p2##y,z,c), I[3] = (T)(img)(_n1##x,_p2##y,z,c), \
556 I[4] = (T)(img)(_n2##x,_p2##y,z,c), I[5] = (T)(img)(_p2##x,_p1##y,z,c), I[6] = (T)(img)(_p1##x,_p1##y,z,c), I[7] = (T)(img)(x,_p1##y,z,c), \
557 I[8] = (T)(img)(_n1##x,_p1##y,z,c), I[9] = (T)(img)(_n2##x,_p1##y,z,c), I[10] = (T)(img)(_p2##x,y,z,c), I[11] = (T)(img)(_p1##x,y,z,c), \
558 I[12] = (T)(img)(x,y,z,c), I[13] = (T)(img)(_n1##x,y,z,c), I[14] = (T)(img)(_n2##x,y,z,c), I[15] = (T)(img)(_p2##x,_n1##y,z,c), \
559 I[16] = (T)(img)(_p1##x,_n1##y,z,c), I[17] = (T)(img)(x,_n1##y,z,c), I[18] = (T)(img)(_n1##x,_n1##y,z,c), I[19] = (T)(img)(_n2##x,_n1##y,z,c), \
560 I[20] = (T)(img)(_p2##x,_n2##y,z,c), I[21] = (T)(img)(_p1##x,_n2##y,z,c), I[22] = (T)(img)(x,_n2##y,z,c), I[23] = (T)(img)(_n1##x,_n2##y,z,c), \
561 I[24] = (T)(img)(_n2##x,_n2##y,z,c)
563 #define cimg_get6x6(img,x,y,z,c,I,T) \
564 I[0] = (T)(img)(_p2##x,_p2##y,z,c), I[1] = (T)(img)(_p1##x,_p2##y,z,c), I[2] = (T)(img)(x,_p2##y,z,c), I[3] = (T)(img)(_n1##x,_p2##y,z,c), \
565 I[4] = (T)(img)(_n2##x,_p2##y,z,c), I[5] = (T)(img)(_n3##x,_p2##y,z,c), I[6] = (T)(img)(_p2##x,_p1##y,z,c), I[7] = (T)(img)(_p1##x,_p1##y,z,c), \
566 I[8] = (T)(img)(x,_p1##y,z,c), I[9] = (T)(img)(_n1##x,_p1##y,z,c), I[10] = (T)(img)(_n2##x,_p1##y,z,c), I[11] = (T)(img)(_n3##x,_p1##y,z,c), \
567 I[12] = (T)(img)(_p2##x,y,z,c), I[13] = (T)(img)(_p1##x,y,z,c), I[14] = (T)(img)(x,y,z,c), I[15] = (T)(img)(_n1##x,y,z,c), \
568 I[16] = (T)(img)(_n2##x,y,z,c), I[17] = (T)(img)(_n3##x,y,z,c), I[18] = (T)(img)(_p2##x,_n1##y,z,c), I[19] = (T)(img)(_p1##x,_n1##y,z,c), \
569 I[20] = (T)(img)(x,_n1##y,z,c), I[21] = (T)(img)(_n1##x,_n1##y,z,c), I[22] = (T)(img)(_n2##x,_n1##y,z,c), I[23] = (T)(img)(_n3##x,_n1##y,z,c), \
570 I[24] = (T)(img)(_p2##x,_n2##y,z,c), I[25] = (T)(img)(_p1##x,_n2##y,z,c), I[26] = (T)(img)(x,_n2##y,z,c), I[27] = (T)(img)(_n1##x,_n2##y,z,c), \
571 I[28] = (T)(img)(_n2##x,_n2##y,z,c), I[29] = (T)(img)(_n3##x,_n2##y,z,c), I[30] = (T)(img)(_p2##x,_n3##y,z,c), I[31] = (T)(img)(_p1##x,_n3##y,z,c), \
572 I[32] = (T)(img)(x,_n3##y,z,c), I[33] = (T)(img)(_n1##x,_n3##y,z,c), I[34] = (T)(img)(_n2##x,_n3##y,z,c), I[35] = (T)(img)(_n3##x,_n3##y,z,c)
574 #define cimg_get7x7(img,x,y,z,c,I,T) \
575 I[0] = (T)(img)(_p3##x,_p3##y,z,c), I[1] = (T)(img)(_p2##x,_p3##y,z,c), I[2] = (T)(img)(_p1##x,_p3##y,z,c), I[3] = (T)(img)(x,_p3##y,z,c), \
576 I[4] = (T)(img)(_n1##x,_p3##y,z,c), I[5] = (T)(img)(_n2##x,_p3##y,z,c), I[6] = (T)(img)(_n3##x,_p3##y,z,c), I[7] = (T)(img)(_p3##x,_p2##y,z,c), \
577 I[8] = (T)(img)(_p2##x,_p2##y,z,c), I[9] = (T)(img)(_p1##x,_p2##y,z,c), I[10] = (T)(img)(x,_p2##y,z,c), I[11] = (T)(img)(_n1##x,_p2##y,z,c), \
578 I[12] = (T)(img)(_n2##x,_p2##y,z,c), I[13] = (T)(img)(_n3##x,_p2##y,z,c), I[14] = (T)(img)(_p3##x,_p1##y,z,c), I[15] = (T)(img)(_p2##x,_p1##y,z,c), \
579 I[16] = (T)(img)(_p1##x,_p1##y,z,c), I[17] = (T)(img)(x,_p1##y,z,c), I[18] = (T)(img)(_n1##x,_p1##y,z,c), I[19] = (T)(img)(_n2##x,_p1##y,z,c), \
580 I[20] = (T)(img)(_n3##x,_p1##y,z,c), I[21] = (T)(img)(_p3##x,y,z,c), I[22] = (T)(img)(_p2##x,y,z,c), I[23] = (T)(img)(_p1##x,y,z,c), \
581 I[24] = (T)(img)(x,y,z,c), I[25] = (T)(img)(_n1##x,y,z,c), I[26] = (T)(img)(_n2##x,y,z,c), I[27] = (T)(img)(_n3##x,y,z,c), \
582 I[28] = (T)(img)(_p3##x,_n1##y,z,c), I[29] = (T)(img)(_p2##x,_n1##y,z,c), I[30] = (T)(img)(_p1##x,_n1##y,z,c), I[31] = (T)(img)(x,_n1##y,z,c), \
583 I[32] = (T)(img)(_n1##x,_n1##y,z,c), I[33] = (T)(img)(_n2##x,_n1##y,z,c), I[34] = (T)(img)(_n3##x,_n1##y,z,c), I[35] = (T)(img)(_p3##x,_n2##y,z,c), \
584 I[36] = (T)(img)(_p2##x,_n2##y,z,c), I[37] = (T)(img)(_p1##x,_n2##y,z,c), I[38] = (T)(img)(x,_n2##y,z,c), I[39] = (T)(img)(_n1##x,_n2##y,z,c), \
585 I[40] = (T)(img)(_n2##x,_n2##y,z,c), I[41] = (T)(img)(_n3##x,_n2##y,z,c), I[42] = (T)(img)(_p3##x,_n3##y,z,c), I[43] = (T)(img)(_p2##x,_n3##y,z,c), \
586 I[44] = (T)(img)(_p1##x,_n3##y,z,c), I[45] = (T)(img)(x,_n3##y,z,c), I[46] = (T)(img)(_n1##x,_n3##y,z,c), I[47] = (T)(img)(_n2##x,_n3##y,z,c), \
587 I[48] = (T)(img)(_n3##x,_n3##y,z,c)
589 #define cimg_get8x8(img,x,y,z,c,I,T) \
590 I[0] = (T)(img)(_p3##x,_p3##y,z,c), I[1] = (T)(img)(_p2##x,_p3##y,z,c), I[2] = (T)(img)(_p1##x,_p3##y,z,c), I[3] = (T)(img)(x,_p3##y,z,c), \
591 I[4] = (T)(img)(_n1##x,_p3##y,z,c), I[5] = (T)(img)(_n2##x,_p3##y,z,c), I[6] = (T)(img)(_n3##x,_p3##y,z,c), I[7] = (T)(img)(_n4##x,_p3##y,z,c), \
592 I[8] = (T)(img)(_p3##x,_p2##y,z,c), I[9] = (T)(img)(_p2##x,_p2##y,z,c), I[10] = (T)(img)(_p1##x,_p2##y,z,c), I[11] = (T)(img)(x,_p2##y,z,c), \
593 I[12] = (T)(img)(_n1##x,_p2##y,z,c), I[13] = (T)(img)(_n2##x,_p2##y,z,c), I[14] = (T)(img)(_n3##x,_p2##y,z,c), I[15] = (T)(img)(_n4##x,_p2##y,z,c), \
594 I[16] = (T)(img)(_p3##x,_p1##y,z,c), I[17] = (T)(img)(_p2##x,_p1##y,z,c), I[18] = (T)(img)(_p1##x,_p1##y,z,c), I[19] = (T)(img)(x,_p1##y,z,c), \
595 I[20] = (T)(img)(_n1##x,_p1##y,z,c), I[21] = (T)(img)(_n2##x,_p1##y,z,c), I[22] = (T)(img)(_n3##x,_p1##y,z,c), I[23] = (T)(img)(_n4##x,_p1##y,z,c), \
596 I[24] = (T)(img)(_p3##x,y,z,c), I[25] = (T)(img)(_p2##x,y,z,c), I[26] = (T)(img)(_p1##x,y,z,c), I[27] = (T)(img)(x,y,z,c), \
597 I[28] = (T)(img)(_n1##x,y,z,c), I[29] = (T)(img)(_n2##x,y,z,c), I[30] = (T)(img)(_n3##x,y,z,c), I[31] = (T)(img)(_n4##x,y,z,c), \
598 I[32] = (T)(img)(_p3##x,_n1##y,z,c), I[33] = (T)(img)(_p2##x,_n1##y,z,c), I[34] = (T)(img)(_p1##x,_n1##y,z,c), I[35] = (T)(img)(x,_n1##y,z,c), \
599 I[36] = (T)(img)(_n1##x,_n1##y,z,c), I[37] = (T)(img)(_n2##x,_n1##y,z,c), I[38] = (T)(img)(_n3##x,_n1##y,z,c), I[39] = (T)(img)(_n4##x,_n1##y,z,c), \
600 I[40] = (T)(img)(_p3##x,_n2##y,z,c), I[41] = (T)(img)(_p2##x,_n2##y,z,c), I[42] = (T)(img)(_p1##x,_n2##y,z,c), I[43] = (T)(img)(x,_n2##y,z,c), \
601 I[44] = (T)(img)(_n1##x,_n2##y,z,c), I[45] = (T)(img)(_n2##x,_n2##y,z,c), I[46] = (T)(img)(_n3##x,_n2##y,z,c), I[47] = (T)(img)(_n4##x,_n2##y,z,c), \
602 I[48] = (T)(img)(_p3##x,_n3##y,z,c), I[49] = (T)(img)(_p2##x,_n3##y,z,c), I[50] = (T)(img)(_p1##x,_n3##y,z,c), I[51] = (T)(img)(x,_n3##y,z,c), \
603 I[52] = (T)(img)(_n1##x,_n3##y,z,c), I[53] = (T)(img)(_n2##x,_n3##y,z,c), I[54] = (T)(img)(_n3##x,_n3##y,z,c), I[55] = (T)(img)(_n4##x,_n3##y,z,c), \
604 I[56] = (T)(img)(_p3##x,_n4##y,z,c), I[57] = (T)(img)(_p2##x,_n4##y,z,c), I[58] = (T)(img)(_p1##x,_n4##y,z,c), I[59] = (T)(img)(x,_n4##y,z,c), \
605 I[60] = (T)(img)(_n1##x,_n4##y,z,c), I[61] = (T)(img)(_n2##x,_n4##y,z,c), I[62] = (T)(img)(_n3##x,_n4##y,z,c), I[63] = (T)(img)(_n4##x,_n4##y,z,c);
607 #define cimg_get9x9(img,x,y,z,c,I,T) \
608 I[0] = (T)(img)(_p4##x,_p4##y,z,c), I[1] = (T)(img)(_p3##x,_p4##y,z,c), I[2] = (T)(img)(_p2##x,_p4##y,z,c), I[3] = (T)(img)(_p1##x,_p4##y,z,c), \
609 I[4] = (T)(img)(x,_p4##y,z,c), I[5] = (T)(img)(_n1##x,_p4##y,z,c), I[6] = (T)(img)(_n2##x,_p4##y,z,c), I[7] = (T)(img)(_n3##x,_p4##y,z,c), \
610 I[8] = (T)(img)(_n4##x,_p4##y,z,c), I[9] = (T)(img)(_p4##x,_p3##y,z,c), I[10] = (T)(img)(_p3##x,_p3##y,z,c), I[11] = (T)(img)(_p2##x,_p3##y,z,c), \
611 I[12] = (T)(img)(_p1##x,_p3##y,z,c), I[13] = (T)(img)(x,_p3##y,z,c), I[14] = (T)(img)(_n1##x,_p3##y,z,c), I[15] = (T)(img)(_n2##x,_p3##y,z,c), \
612 I[16] = (T)(img)(_n3##x,_p3##y,z,c), I[17] = (T)(img)(_n4##x,_p3##y,z,c), I[18] = (T)(img)(_p4##x,_p2##y,z,c), I[19] = (T)(img)(_p3##x,_p2##y,z,c), \
613 I[20] = (T)(img)(_p2##x,_p2##y,z,c), I[21] = (T)(img)(_p1##x,_p2##y,z,c), I[22] = (T)(img)(x,_p2##y,z,c), I[23] = (T)(img)(_n1##x,_p2##y,z,c), \
614 I[24] = (T)(img)(_n2##x,_p2##y,z,c), I[25] = (T)(img)(_n3##x,_p2##y,z,c), I[26] = (T)(img)(_n4##x,_p2##y,z,c), I[27] = (T)(img)(_p4##x,_p1##y,z,c), \
615 I[28] = (T)(img)(_p3##x,_p1##y,z,c), I[29] = (T)(img)(_p2##x,_p1##y,z,c), I[30] = (T)(img)(_p1##x,_p1##y,z,c), I[31] = (T)(img)(x,_p1##y,z,c), \
616 I[32] = (T)(img)(_n1##x,_p1##y,z,c), I[33] = (T)(img)(_n2##x,_p1##y,z,c), I[34] = (T)(img)(_n3##x,_p1##y,z,c), I[35] = (T)(img)(_n4##x,_p1##y,z,c), \
617 I[36] = (T)(img)(_p4##x,y,z,c), I[37] = (T)(img)(_p3##x,y,z,c), I[38] = (T)(img)(_p2##x,y,z,c), I[39] = (T)(img)(_p1##x,y,z,c), \
618 I[40] = (T)(img)(x,y,z,c), I[41] = (T)(img)(_n1##x,y,z,c), I[42] = (T)(img)(_n2##x,y,z,c), I[43] = (T)(img)(_n3##x,y,z,c), \
619 I[44] = (T)(img)(_n4##x,y,z,c), I[45] = (T)(img)(_p4##x,_n1##y,z,c), I[46] = (T)(img)(_p3##x,_n1##y,z,c), I[47] = (T)(img)(_p2##x,_n1##y,z,c), \
620 I[48] = (T)(img)(_p1##x,_n1##y,z,c), I[49] = (T)(img)(x,_n1##y,z,c), I[50] = (T)(img)(_n1##x,_n1##y,z,c), I[51] = (T)(img)(_n2##x,_n1##y,z,c), \
621 I[52] = (T)(img)(_n3##x,_n1##y,z,c), I[53] = (T)(img)(_n4##x,_n1##y,z,c), I[54] = (T)(img)(_p4##x,_n2##y,z,c), I[55] = (T)(img)(_p3##x,_n2##y,z,c), \
622 I[56] = (T)(img)(_p2##x,_n2##y,z,c), I[57] = (T)(img)(_p1##x,_n2##y,z,c), I[58] = (T)(img)(x,_n2##y,z,c), I[59] = (T)(img)(_n1##x,_n2##y,z,c), \
623 I[60] = (T)(img)(_n2##x,_n2##y,z,c), I[61] = (T)(img)(_n3##x,_n2##y,z,c), I[62] = (T)(img)(_n4##x,_n2##y,z,c), I[63] = (T)(img)(_p4##x,_n3##y,z,c), \
624 I[64] = (T)(img)(_p3##x,_n3##y,z,c), I[65] = (T)(img)(_p2##x,_n3##y,z,c), I[66] = (T)(img)(_p1##x,_n3##y,z,c), I[67] = (T)(img)(x,_n3##y,z,c), \
625 I[68] = (T)(img)(_n1##x,_n3##y,z,c), I[69] = (T)(img)(_n2##x,_n3##y,z,c), I[70] = (T)(img)(_n3##x,_n3##y,z,c), I[71] = (T)(img)(_n4##x,_n3##y,z,c), \
626 I[72] = (T)(img)(_p4##x,_n4##y,z,c), I[73] = (T)(img)(_p3##x,_n4##y,z,c), I[74] = (T)(img)(_p2##x,_n4##y,z,c), I[75] = (T)(img)(_p1##x,_n4##y,z,c), \
627 I[76] = (T)(img)(x,_n4##y,z,c), I[77] = (T)(img)(_n1##x,_n4##y,z,c), I[78] = (T)(img)(_n2##x,_n4##y,z,c), I[79] = (T)(img)(_n3##x,_n4##y,z,c), \
628 I[80] = (T)(img)(_n4##x,_n4##y,z,c)
630 #define cimg_get2x2x2(img,x,y,z,c,I,T) \
631 I[0] = (T)(img)(x,y,z,c), I[1] = (T)(img)(_n1##x,y,z,c), I[2] = (T)(img)(x,_n1##y,z,c), I[3] = (T)(img)(_n1##x,_n1##y,z,c), \
632 I[4] = (T)(img)(x,y,_n1##z,c), I[5] = (T)(img)(_n1##x,y,_n1##z,c), I[6] = (T)(img)(x,_n1##y,_n1##z,c), I[7] = (T)(img)(_n1##x,_n1##y,_n1##z,c)
634 #define cimg_get3x3x3(img,x,y,z,c,I,T) \
635 I[0] = (T)(img)(_p1##x,_p1##y,_p1##z,c), I[1] = (T)(img)(x,_p1##y,_p1##z,c), I[2] = (T)(img)(_n1##x,_p1##y,_p1##z,c), \
636 I[3] = (T)(img)(_p1##x,y,_p1##z,c), I[4] = (T)(img)(x,y,_p1##z,c), I[5] = (T)(img)(_n1##x,y,_p1##z,c), \
637 I[6] = (T)(img)(_p1##x,_n1##y,_p1##z,c), I[7] = (T)(img)(x,_n1##y,_p1##z,c), I[8] = (T)(img)(_n1##x,_n1##y,_p1##z,c), \
638 I[9] = (T)(img)(_p1##x,_p1##y,z,c), I[10] = (T)(img)(x,_p1##y,z,c), I[11] = (T)(img)(_n1##x,_p1##y,z,c), \
639 I[12] = (T)(img)(_p1##x,y,z,c), I[13] = (T)(img)(x,y,z,c), I[14] = (T)(img)(_n1##x,y,z,c), \
640 I[15] = (T)(img)(_p1##x,_n1##y,z,c), I[16] = (T)(img)(x,_n1##y,z,c), I[17] = (T)(img)(_n1##x,_n1##y,z,c), \
641 I[18] = (T)(img)(_p1##x,_p1##y,_n1##z,c), I[19] = (T)(img)(x,_p1##y,_n1##z,c), I[20] = (T)(img)(_n1##x,_p1##y,_n1##z,c), \
642 I[21] = (T)(img)(_p1##x,y,_n1##z,c), I[22] = (T)(img)(x,y,_n1##z,c), I[23] = (T)(img)(_n1##x,y,_n1##z,c), \
643 I[24] = (T)(img)(_p1##x,_n1##y,_n1##z,c), I[25] = (T)(img)(x,_n1##y,_n1##z,c), I[26] = (T)(img)(_n1##x,_n1##y,_n1##z,c)
648 #define cimg_for(img,ptrs,T_ptrs) for (T_ptrs *ptrs = (img)._data, *_max##ptrs = (img)._data + (img).size(); ptrs<_max##ptrs; ++ptrs)
649 #define cimg_rof(img,ptrs,T_ptrs) for (T_ptrs *ptrs = (img)._data + (img).size(); (ptrs--)>(img)._data; )
650 #define cimg_foroff(img,off) for (unsigned long off = 0, _max##off = (img).size(); off<_max##off; ++off)
652 #define cimg_for1(bound,i) for (int i = 0; i<(int)(bound); ++i)
653 #define cimg_forX(img,x) cimg_for1((img)._width,x)
654 #define cimg_forY(img,y) cimg_for1((img)._height,y)
655 #define cimg_forZ(img,z) cimg_for1((img)._depth,z)
656 #define cimg_forC(img,c) cimg_for1((img)._spectrum,c)
657 #define cimg_forXY(img,x,y) cimg_forY(img,y) cimg_forX(img,x)
658 #define cimg_forXZ(img,x,z) cimg_forZ(img,z) cimg_forX(img,x)
659 #define cimg_forYZ(img,y,z) cimg_forZ(img,z) cimg_forY(img,y)
660 #define cimg_forXC(img,x,c) cimg_forC(img,c) cimg_forX(img,x)
661 #define cimg_forYC(img,y,c) cimg_forC(img,c) cimg_forY(img,y)
662 #define cimg_forZC(img,z,c) cimg_forC(img,c) cimg_forZ(img,z)
663 #define cimg_forXYZ(img,x,y,z) cimg_forZ(img,z) cimg_forXY(img,x,y)
664 #define cimg_forXYC(img,x,y,c) cimg_forC(img,c) cimg_forXY(img,x,y)
665 #define cimg_forXZC(img,x,z,c) cimg_forC(img,c) cimg_forXZ(img,x,z)
666 #define cimg_forYZC(img,y,z,c) cimg_forC(img,c) cimg_forYZ(img,y,z)
667 #define cimg_forXYZC(img,x,y,z,c) cimg_forC(img,c) cimg_forXYZ(img,x,y,z)
669 #define cimg_for_in1(bound,i0,i1,i) \
670 for (int i = (int)(i0)<0?0:(int)(i0), _max##i = (int)(i1)<(int)(bound)?(int)(i1):(int)(bound)-1; i<=_max##i; ++i)
671 #define cimg_for_inX(img,x0,x1,x) cimg_for_in1((img)._width,x0,x1,x)
672 #define cimg_for_inY(img,y0,y1,y) cimg_for_in1((img)._height,y0,y1,y)
673 #define cimg_for_inZ(img,z0,z1,z) cimg_for_in1((img)._depth,z0,z1,z)
674 #define cimg_for_inC(img,c0,c1,c) cimg_for_in1((img)._spectrum,c0,c1,c)
675 #define cimg_for_inXY(img,x0,y0,x1,y1,x,y) cimg_for_inY(img,y0,y1,y) cimg_for_inX(img,x0,x1,x)
676 #define cimg_for_inXZ(img,x0,z0,x1,z1,x,z) cimg_for_inZ(img,z0,z1,z) cimg_for_inX(img,x0,x1,x)
677 #define cimg_for_inXC(img,x0,c0,x1,c1,x,c) cimg_for_inC(img,c0,c1,c) cimg_for_inX(img,x0,x1,x)
678 #define cimg_for_inYZ(img,y0,z0,y1,z1,y,z) cimg_for_inZ(img,x0,z1,z) cimg_for_inY(img,y0,y1,y)
679 #define cimg_for_inYC(img,y0,c0,y1,c1,y,c) cimg_for_inC(img,c0,c1,c) cimg_for_inY(img,y0,y1,y)
680 #define cimg_for_inZC(img,z0,c0,z1,c1,z,c) cimg_for_inC(img,c0,c1,c) cimg_for_inZ(img,z0,z1,z)
681 #define cimg_for_inXYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_inZ(img,z0,z1,z) cimg_for_inXY(img,x0,y0,x1,y1,x,y)
682 #define cimg_for_inXYC(img,x0,y0,c0,x1,y1,c1,x,y,c) cimg_for_inC(img,c0,c1,c) cimg_for_inXY(img,x0,y0,x1,y1,x,y)
683 #define cimg_for_inXZC(img,x0,z0,c0,x1,z1,c1,x,z,c) cimg_for_inC(img,c0,c1,c) cimg_for_inXZ(img,x0,z0,x1,z1,x,z)
684 #define cimg_for_inYZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_inC(img,c0,c1,c) cimg_for_inYZ(img,y0,z0,y1,z1,y,z)
685 #define cimg_for_inXYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_inC(img,c0,c1,c) cimg_for_inXYZ(img,x0,y0,z0,x1,y1,z1,x,y,z)
686 #define cimg_for_insideX(img,x,n) cimg_for_inX(img,n,(img)._width-1-(n),x)
687 #define cimg_for_insideY(img,y,n) cimg_for_inY(img,n,(img)._height-1-(n),y)
688 #define cimg_for_insideZ(img,z,n) cimg_for_inZ(img,n,(img)._depth-1-(n),z)
689 #define cimg_for_insideC(img,c,n) cimg_for_inC(img,n,(img)._spectrum-1-(n),c)
690 #define cimg_for_insideXY(img,x,y,n) cimg_for_inXY(img,n,n,(img)._width-1-(n),(img)._height-1-(n),x,y)
691 #define cimg_for_insideXYZ(img,x,y,z,n) cimg_for_inXYZ(img,n,n,n,(img)._width-1-(n),(img)._height-1-(n),(img)._depth-1-(n),x,y,z)
692 #define cimg_for_insideXYZC(img,x,y,z,c,n) cimg_for_inXYZ(img,n,n,n,(img)._width-1-(n),(img)._height-1-(n),(img)._depth-1-(n),x,y,z)
694 #define cimg_for_out1(boundi,i0,i1,i) \
695 for (int i = (int)(i0)>0?0:(int)(i1)+1; i<(int)(boundi); ++i, i = i==(int)(i0)?(int)(i1)+1:i)
696 #define cimg_for_out2(boundi,boundj,i0,j0,i1,j1,i,j) \
697 for (int j = 0; j<(int)(boundj); ++j) \
698 for (int _n1j = (int)(j<(int)(j0) || j>(int)(j1)), i = _n1j?0:(int)(i0)>0?0:(int)(i1)+1; i<(int)(boundi); \
699 ++i, i = _n1j?i:(i==(int)(i0)?(int)(i1)+1:i))
700 #define cimg_for_out3(boundi,boundj,boundk,i0,j0,k0,i1,j1,k1,i,j,k) \
701 for (int k = 0; k<(int)(boundk); ++k) \
702 for (int _n1k = (int)(k<(int)(k0) || k>(int)(k1)), j = 0; j<(int)(boundj); ++j) \
703 for (int _n1j = (int)(j<(int)(j0) || j>(int)(j1)), i = _n1j || _n1k?0:(int)(i0)>0?0:(int)(i1)+1; i<(int)(boundi); \
704 ++i, i = _n1j || _n1k?i:(i==(int)(i0)?(int)(i1)+1:i))
705 #define cimg_for_out4(boundi,boundj,boundk,boundl,i0,j0,k0,l0,i1,j1,k1,l1,i,j,k,l) \
706 for (int l = 0; l<(int)(boundl); ++l) \
707 for (int _n1l = (int)(l<(int)(l0) || l>(int)(l1)), k = 0; k<(int)(boundk); ++k) \
708 for (int _n1k = (int)(k<(int)(k0) || k>(int)(k1)), j = 0; j<(int)(boundj); ++j) \
709 for (int _n1j = (int)(j<(int)(j0) || j>(int)(j1)), i = _n1j || _n1k || _n1l?0:(int)(i0)>0?0:(int)(i1)+1; i<(int)(boundi); \
710 ++i, i = _n1j || _n1k || _n1l?i:(i==(int)(i0)?(int)(i1)+1:i))
711 #define cimg_for_outX(img,x0,x1,x) cimg_for_out1((img)._width,x0,x1,x)
712 #define cimg_for_outY(img,y0,y1,y) cimg_for_out1((img)._height,y0,y1,y)
713 #define cimg_for_outZ(img,z0,z1,z) cimg_for_out1((img)._depth,z0,z1,z)
714 #define cimg_for_outC(img,c0,c1,c) cimg_for_out1((img)._spectrum,c0,c1,c)
715 #define cimg_for_outXY(img,x0,y0,x1,y1,x,y) cimg_for_out2((img)._width,(img)._height,x0,y0,x1,y1,x,y)
716 #define cimg_for_outXZ(img,x0,z0,x1,z1,x,z) cimg_for_out2((img)._width,(img)._depth,x0,z0,x1,z1,x,z)
717 #define cimg_for_outXC(img,x0,c0,x1,c1,x,c) cimg_for_out2((img)._width,(img)._spectrum,x0,c0,x1,c1,x,c)
718 #define cimg_for_outYZ(img,y0,z0,y1,z1,y,z) cimg_for_out2((img)._height,(img)._depth,y0,z0,y1,z1,y,z)
719 #define cimg_for_outYC(img,y0,c0,y1,c1,y,c) cimg_for_out2((img)._height,(img)._spectrum,y0,c0,y1,c1,y,c)
720 #define cimg_for_outZC(img,z0,c0,z1,c1,z,c) cimg_for_out2((img)._depth,(img)._spectrum,z0,c0,z1,c1,z,c)
721 #define cimg_for_outXYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_out3((img)._width,(img)._height,(img)._depth,x0,y0,z0,x1,y1,z1,x,y,z)
722 #define cimg_for_outXYC(img,x0,y0,c0,x1,y1,c1,x,y,c) cimg_for_out3((img)._width,(img)._height,(img)._spectrum,x0,y0,c0,x1,y1,c1,x,y,c)
723 #define cimg_for_outXZC(img,x0,z0,c0,x1,z1,c1,x,z,c) cimg_for_out3((img)._width,(img)._depth,(img)._spectrum,x0,z0,c0,x1,z1,c1,x,z,c)
724 #define cimg_for_outYZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_out3((img)._height,(img)._depth,(img)._spectrum,y0,z0,c0,y1,z1,c1,y,z,c)
725 #define cimg_for_outXYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) \
726 cimg_for_out4((img)._width,(img)._height,(img)._depth,(img)._spectrum,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c)
727 #define cimg_for_borderX(img,x,n) cimg_for_outX(img,n,(img)._width-1-(n),x)
728 #define cimg_for_borderY(img,y,n) cimg_for_outY(img,n,(img)._height-1-(n),y)
729 #define cimg_for_borderZ(img,z,n) cimg_for_outZ(img,n,(img)._depth-1-(n),z)
730 #define cimg_for_borderC(img,c,n) cimg_for_outC(img,n,(img)._spectrum-1-(n),c)
731 #define cimg_for_borderXY(img,x,y,n) cimg_for_outXY(img,n,n,(img)._width-1-(n),(img)._height-1-(n),x,y)
732 #define cimg_for_borderXYZ(img,x,y,z,n) cimg_for_outXYZ(img,n,n,n,(img)._width-1-(n),(img)._height-1-(n),(img)._depth-1-(n),x,y,z)
733 #define cimg_for_borderXYZC(img,x,y,z,c,n) \
734 cimg_for_outXYZC(img,n,n,n,n,(img)._width-1-(n),(img)._height-1-(n),(img)._depth-1-(n),(img)._spectrum-1-(n),x,y,z,c)
736 #define cimg_for_spiralXY(img,x,y) \
737 for (int x = 0, y = 0, _n1##x = 1, _n1##y = (img).width()*(img).height(); _n1##y; \
738 --_n1##y, _n1##x+=(_n1##x>>2)-((!(_n1##x&3)?--y:((_n1##x&3)==1?(img)._width-1-++x:((_n1##x&3)==2?(img)._height-1-++y:--x))))?0:1)
740 #define cimg_for_lineXY(x,y,x0,y0,x1,y1) \
741 for (int x = (int)(x0), y = (int)(y0), _sx = 1, _sy = 1, _steep = 0, \
742 _dx=(x1)>(x0)?(int)(x1)-(int)(x0):(_sx=-1,(int)(x0)-(int)(x1)), \
743 _dy=(y1)>(y0)?(int)(y1)-(int)(y0):(_sy=-1,(int)(y0)-(int)(y1)), \
745 _err = _dx>_dy?(_dy>>1):((_steep=1),(_counter=_dy),(_dx>>1)); \
747 --_counter, x+=_steep? \
748 (y+=_sy,(_err-=_dx)<0?_err+=_dy,_sx:0): \
749 (y+=(_err-=_dy)<0?_err+=_dx,_sy:0,_sx))
751 #define cimg_for2(bound,i) \
752 for (int i = 0, _n1##i = 1>=(bound)?(int)(bound)-1:1; \
753 _n1##i<(int)(bound) || i==--_n1##i; \
755 #define cimg_for2X(img,x) cimg_for2((img)._width,x)
756 #define cimg_for2Y(img,y) cimg_for2((img)._height,y)
757 #define cimg_for2Z(img,z) cimg_for2((img)._depth,z)
758 #define cimg_for2C(img,c) cimg_for2((img)._spectrum,c)
759 #define cimg_for2XY(img,x,y) cimg_for2Y(img,y) cimg_for2X(img,x)
760 #define cimg_for2XZ(img,x,z) cimg_for2Z(img,z) cimg_for2X(img,x)
761 #define cimg_for2XC(img,x,c) cimg_for2C(img,c) cimg_for2X(img,x)
762 #define cimg_for2YZ(img,y,z) cimg_for2Z(img,z) cimg_for2Y(img,y)
763 #define cimg_for2YC(img,y,c) cimg_for2C(img,c) cimg_for2Y(img,y)
764 #define cimg_for2ZC(img,z,c) cimg_for2C(img,c) cimg_for2Z(img,z)
765 #define cimg_for2XYZ(img,x,y,z) cimg_for2Z(img,z) cimg_for2XY(img,x,y)
766 #define cimg_for2XZC(img,x,z,c) cimg_for2C(img,c) cimg_for2XZ(img,x,z)
767 #define cimg_for2YZC(img,y,z,c) cimg_for2C(img,c) cimg_for2YZ(img,y,z)
768 #define cimg_for2XYZC(img,x,y,z,c) cimg_for2C(img,c) cimg_for2XYZ(img,x,y,z)
770 #define cimg_for_in2(bound,i0,i1,i) \
771 for (int i = (int)(i0)<0?0:(int)(i0), \
772 _n1##i = i+1>=(int)(bound)?(int)(bound)-1:i+1; \
773 i<=(int)(i1) && (_n1##i<(int)(bound) || i==--_n1##i); \
775 #define cimg_for_in2X(img,x0,x1,x) cimg_for_in2((img)._width,x0,x1,x)
776 #define cimg_for_in2Y(img,y0,y1,y) cimg_for_in2((img)._height,y0,y1,y)
777 #define cimg_for_in2Z(img,z0,z1,z) cimg_for_in2((img)._depth,z0,z1,z)
778 #define cimg_for_in2C(img,c0,c1,c) cimg_for_in2((img)._spectrum,c0,c1,c)
779 #define cimg_for_in2XY(img,x0,y0,x1,y1,x,y) cimg_for_in2Y(img,y0,y1,y) cimg_for_in2X(img,x0,x1,x)
780 #define cimg_for_in2XZ(img,x0,z0,x1,z1,x,z) cimg_for_in2Z(img,z0,z1,z) cimg_for_in2X(img,x0,x1,x)
781 #define cimg_for_in2XC(img,x0,c0,x1,c1,x,c) cimg_for_in2C(img,c0,c1,c) cimg_for_in2X(img,x0,x1,x)
782 #define cimg_for_in2YZ(img,y0,z0,y1,z1,y,z) cimg_for_in2Z(img,z0,z1,z) cimg_for_in2Y(img,y0,y1,y)
783 #define cimg_for_in2YC(img,y0,c0,y1,c1,y,c) cimg_for_in2C(img,c0,c1,c) cimg_for_in2Y(img,y0,y1,y)
784 #define cimg_for_in2ZC(img,z0,c0,z1,c1,z,c) cimg_for_in2C(img,c0,c1,c) cimg_for_in2Z(img,z0,z1,z)
785 #define cimg_for_in2XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in2Z(img,z0,z1,z) cimg_for_in2XY(img,x0,y0,x1,y1,x,y)
786 #define cimg_for_in2XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in2C(img,c0,c1,c) cimg_for_in2XZ(img,x0,y0,x1,y1,x,z)
787 #define cimg_for_in2YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in2C(img,c0,c1,c) cimg_for_in2YZ(img,y0,z0,y1,z1,y,z)
788 #define cimg_for_in2XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_in2C(img,c0,c1,c) cimg_for_in2XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z)
790 #define cimg_for3(bound,i) \
791 for (int i = 0, _p1##i = 0, \
792 _n1##i = 1>=(bound)?(int)(bound)-1:1; \
793 _n1##i<(int)(bound) || i==--_n1##i; \
794 _p1##i = i++, ++_n1##i)
795 #define cimg_for3X(img,x) cimg_for3((img)._width,x)
796 #define cimg_for3Y(img,y) cimg_for3((img)._height,y)
797 #define cimg_for3Z(img,z) cimg_for3((img)._depth,z)
798 #define cimg_for3C(img,c) cimg_for3((img)._spectrum,c)
799 #define cimg_for3XY(img,x,y) cimg_for3Y(img,y) cimg_for3X(img,x)
800 #define cimg_for3XZ(img,x,z) cimg_for3Z(img,z) cimg_for3X(img,x)
801 #define cimg_for3XC(img,x,c) cimg_for3C(img,c) cimg_for3X(img,x)
802 #define cimg_for3YZ(img,y,z) cimg_for3Z(img,z) cimg_for3Y(img,y)
803 #define cimg_for3YC(img,y,c) cimg_for3C(img,c) cimg_for3Y(img,y)
804 #define cimg_for3ZC(img,z,c) cimg_for3C(img,c) cimg_for3Z(img,z)
805 #define cimg_for3XYZ(img,x,y,z) cimg_for3Z(img,z) cimg_for3XY(img,x,y)
806 #define cimg_for3XZC(img,x,z,c) cimg_for3C(img,c) cimg_for3XZ(img,x,z)
807 #define cimg_for3YZC(img,y,z,c) cimg_for3C(img,c) cimg_for3YZ(img,y,z)
808 #define cimg_for3XYZC(img,x,y,z,c) cimg_for3C(img,c) cimg_for3XYZ(img,x,y,z)
810 #define cimg_for_in3(bound,i0,i1,i) \
811 for (int i = (int)(i0)<0?0:(int)(i0), \
812 _p1##i = i-1<0?0:i-1, \
813 _n1##i = i+1>=(int)(bound)?(int)(bound)-1:i+1; \
814 i<=(int)(i1) && (_n1##i<(int)(bound) || i==--_n1##i); \
815 _p1##i = i++, ++_n1##i)
816 #define cimg_for_in3X(img,x0,x1,x) cimg_for_in3((img)._width,x0,x1,x)
817 #define cimg_for_in3Y(img,y0,y1,y) cimg_for_in3((img)._height,y0,y1,y)
818 #define cimg_for_in3Z(img,z0,z1,z) cimg_for_in3((img)._depth,z0,z1,z)
819 #define cimg_for_in3C(img,c0,c1,c) cimg_for_in3((img)._spectrum,c0,c1,c)
820 #define cimg_for_in3XY(img,x0,y0,x1,y1,x,y) cimg_for_in3Y(img,y0,y1,y) cimg_for_in3X(img,x0,x1,x)
821 #define cimg_for_in3XZ(img,x0,z0,x1,z1,x,z) cimg_for_in3Z(img,z0,z1,z) cimg_for_in3X(img,x0,x1,x)
822 #define cimg_for_in3XC(img,x0,c0,x1,c1,x,c) cimg_for_in3C(img,c0,c1,c) cimg_for_in3X(img,x0,x1,x)
823 #define cimg_for_in3YZ(img,y0,z0,y1,z1,y,z) cimg_for_in3Z(img,z0,z1,z) cimg_for_in3Y(img,y0,y1,y)
824 #define cimg_for_in3YC(img,y0,c0,y1,c1,y,c) cimg_for_in3C(img,c0,c1,c) cimg_for_in3Y(img,y0,y1,y)
825 #define cimg_for_in3ZC(img,z0,c0,z1,c1,z,c) cimg_for_in3C(img,c0,c1,c) cimg_for_in3Z(img,z0,z1,z)
826 #define cimg_for_in3XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in3Z(img,z0,z1,z) cimg_for_in3XY(img,x0,y0,x1,y1,x,y)
827 #define cimg_for_in3XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in3C(img,c0,c1,c) cimg_for_in3XZ(img,x0,y0,x1,y1,x,z)
828 #define cimg_for_in3YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in3C(img,c0,c1,c) cimg_for_in3YZ(img,y0,z0,y1,z1,y,z)
829 #define cimg_for_in3XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_in3C(img,c0,c1,c) cimg_for_in3XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z)
831 #define cimg_for4(bound,i) \
832 for (int i = 0, _p1##i = 0, _n1##i = 1>=(bound)?(int)(bound)-1:1, \
833 _n2##i = 2>=(bound)?(int)(bound)-1:2; \
834 _n2##i<(int)(bound) || _n1##i==--_n2##i || i==(_n2##i = --_n1##i); \
835 _p1##i = i++, ++_n1##i, ++_n2##i)
836 #define cimg_for4X(img,x) cimg_for4((img)._width,x)
837 #define cimg_for4Y(img,y) cimg_for4((img)._height,y)
838 #define cimg_for4Z(img,z) cimg_for4((img)._depth,z)
839 #define cimg_for4C(img,c) cimg_for4((img)._spectrum,c)
840 #define cimg_for4XY(img,x,y) cimg_for4Y(img,y) cimg_for4X(img,x)
841 #define cimg_for4XZ(img,x,z) cimg_for4Z(img,z) cimg_for4X(img,x)
842 #define cimg_for4XC(img,x,c) cimg_for4C(img,c) cimg_for4X(img,x)
843 #define cimg_for4YZ(img,y,z) cimg_for4Z(img,z) cimg_for4Y(img,y)
844 #define cimg_for4YC(img,y,c) cimg_for4C(img,c) cimg_for4Y(img,y)
845 #define cimg_for4ZC(img,z,c) cimg_for4C(img,c) cimg_for4Z(img,z)
846 #define cimg_for4XYZ(img,x,y,z) cimg_for4Z(img,z) cimg_for4XY(img,x,y)
847 #define cimg_for4XZC(img,x,z,c) cimg_for4C(img,c) cimg_for4XZ(img,x,z)
848 #define cimg_for4YZC(img,y,z,c) cimg_for4C(img,c) cimg_for4YZ(img,y,z)
849 #define cimg_for4XYZC(img,x,y,z,c) cimg_for4C(img,c) cimg_for4XYZ(img,x,y,z)
851 #define cimg_for_in4(bound,i0,i1,i) \
852 for (int i = (int)(i0)<0?0:(int)(i0), \
853 _p1##i = i-1<0?0:i-1, \
854 _n1##i = i+1>=(int)(bound)?(int)(bound)-1:i+1, \
855 _n2##i = i+2>=(int)(bound)?(int)(bound)-1:i+2; \
856 i<=(int)(i1) && (_n2##i<(int)(bound) || _n1##i==--_n2##i || i==(_n2##i = --_n1##i)); \
857 _p1##i = i++, ++_n1##i, ++_n2##i)
858 #define cimg_for_in4X(img,x0,x1,x) cimg_for_in4((img)._width,x0,x1,x)
859 #define cimg_for_in4Y(img,y0,y1,y) cimg_for_in4((img)._height,y0,y1,y)
860 #define cimg_for_in4Z(img,z0,z1,z) cimg_for_in4((img)._depth,z0,z1,z)
861 #define cimg_for_in4C(img,c0,c1,c) cimg_for_in4((img)._spectrum,c0,c1,c)
862 #define cimg_for_in4XY(img,x0,y0,x1,y1,x,y) cimg_for_in4Y(img,y0,y1,y) cimg_for_in4X(img,x0,x1,x)
863 #define cimg_for_in4XZ(img,x0,z0,x1,z1,x,z) cimg_for_in4Z(img,z0,z1,z) cimg_for_in4X(img,x0,x1,x)
864 #define cimg_for_in4XC(img,x0,c0,x1,c1,x,c) cimg_for_in4C(img,c0,c1,c) cimg_for_in4X(img,x0,x1,x)
865 #define cimg_for_in4YZ(img,y0,z0,y1,z1,y,z) cimg_for_in4Z(img,z0,z1,z) cimg_for_in4Y(img,y0,y1,y)
866 #define cimg_for_in4YC(img,y0,c0,y1,c1,y,c) cimg_for_in4C(img,c0,c1,c) cimg_for_in4Y(img,y0,y1,y)
867 #define cimg_for_in4ZC(img,z0,c0,z1,c1,z,c) cimg_for_in4C(img,c0,c1,c) cimg_for_in4Z(img,z0,z1,z)
868 #define cimg_for_in4XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in4Z(img,z0,z1,z) cimg_for_in4XY(img,x0,y0,x1,y1,x,y)
869 #define cimg_for_in4XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in4C(img,c0,c1,c) cimg_for_in4XZ(img,x0,y0,x1,y1,x,z)
870 #define cimg_for_in4YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in4C(img,c0,c1,c) cimg_for_in4YZ(img,y0,z0,y1,z1,y,z)
871 #define cimg_for_in4XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_in4C(img,c0,c1,c) cimg_for_in4XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z)
873 #define cimg_for5(bound,i) \
874 for (int i = 0, _p2##i = 0, _p1##i = 0, \
875 _n1##i = 1>=(bound)?(int)(bound)-1:1, \
876 _n2##i = 2>=(bound)?(int)(bound)-1:2; \
877 _n2##i<(int)(bound) || _n1##i==--_n2##i || i==(_n2##i = --_n1##i); \
878 _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i)
879 #define cimg_for5X(img,x) cimg_for5((img)._width,x)
880 #define cimg_for5Y(img,y) cimg_for5((img)._height,y)
881 #define cimg_for5Z(img,z) cimg_for5((img)._depth,z)
882 #define cimg_for5C(img,c) cimg_for5((img)._spectrum,c)
883 #define cimg_for5XY(img,x,y) cimg_for5Y(img,y) cimg_for5X(img,x)
884 #define cimg_for5XZ(img,x,z) cimg_for5Z(img,z) cimg_for5X(img,x)
885 #define cimg_for5XC(img,x,c) cimg_for5C(img,c) cimg_for5X(img,x)
886 #define cimg_for5YZ(img,y,z) cimg_for5Z(img,z) cimg_for5Y(img,y)
887 #define cimg_for5YC(img,y,c) cimg_for5C(img,c) cimg_for5Y(img,y)
888 #define cimg_for5ZC(img,z,c) cimg_for5C(img,c) cimg_for5Z(img,z)
889 #define cimg_for5XYZ(img,x,y,z) cimg_for5Z(img,z) cimg_for5XY(img,x,y)
890 #define cimg_for5XZC(img,x,z,c) cimg_for5C(img,c) cimg_for5XZ(img,x,z)
891 #define cimg_for5YZC(img,y,z,c) cimg_for5C(img,c) cimg_for5YZ(img,y,z)
892 #define cimg_for5XYZC(img,x,y,z,c) cimg_for5C(img,c) cimg_for5XYZ(img,x,y,z)
894 #define cimg_for_in5(bound,i0,i1,i) \
895 for (int i = (int)(i0)<0?0:(int)(i0), \
896 _p2##i = i-2<0?0:i-2, \
897 _p1##i = i-1<0?0:i-1, \
898 _n1##i = i+1>=(int)(bound)?(int)(bound)-1:i+1, \
899 _n2##i = i+2>=(int)(bound)?(int)(bound)-1:i+2; \
900 i<=(int)(i1) && (_n2##i<(int)(bound) || _n1##i==--_n2##i || i==(_n2##i = --_n1##i)); \
901 _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i)
902 #define cimg_for_in5X(img,x0,x1,x) cimg_for_in5((img)._width,x0,x1,x)
903 #define cimg_for_in5Y(img,y0,y1,y) cimg_for_in5((img)._height,y0,y1,y)
904 #define cimg_for_in5Z(img,z0,z1,z) cimg_for_in5((img)._depth,z0,z1,z)
905 #define cimg_for_in5C(img,c0,c1,c) cimg_for_in5((img)._spectrum,c0,c1,c)
906 #define cimg_for_in5XY(img,x0,y0,x1,y1,x,y) cimg_for_in5Y(img,y0,y1,y) cimg_for_in5X(img,x0,x1,x)
907 #define cimg_for_in5XZ(img,x0,z0,x1,z1,x,z) cimg_for_in5Z(img,z0,z1,z) cimg_for_in5X(img,x0,x1,x)
908 #define cimg_for_in5XC(img,x0,c0,x1,c1,x,c) cimg_for_in5C(img,c0,c1,c) cimg_for_in5X(img,x0,x1,x)
909 #define cimg_for_in5YZ(img,y0,z0,y1,z1,y,z) cimg_for_in5Z(img,z0,z1,z) cimg_for_in5Y(img,y0,y1,y)
910 #define cimg_for_in5YC(img,y0,c0,y1,c1,y,c) cimg_for_in5C(img,c0,c1,c) cimg_for_in5Y(img,y0,y1,y)
911 #define cimg_for_in5ZC(img,z0,c0,z1,c1,z,c) cimg_for_in5C(img,c0,c1,c) cimg_for_in5Z(img,z0,z1,z)
912 #define cimg_for_in5XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in5Z(img,z0,z1,z) cimg_for_in5XY(img,x0,y0,x1,y1,x,y)
913 #define cimg_for_in5XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in5C(img,c0,c1,c) cimg_for_in5XZ(img,x0,y0,x1,y1,x,z)
914 #define cimg_for_in5YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in5C(img,c0,c1,c) cimg_for_in5YZ(img,y0,z0,y1,z1,y,z)
915 #define cimg_for_in5XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_in5C(img,c0,c1,c) cimg_for_in5XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z)
917 #define cimg_for6(bound,i) \
918 for (int i = 0, _p2##i = 0, _p1##i = 0, \
919 _n1##i = 1>=(bound)?(int)(bound)-1:1, \
920 _n2##i = 2>=(bound)?(int)(bound)-1:2, \
921 _n3##i = 3>=(bound)?(int)(bound)-1:3; \
922 _n3##i<(int)(bound) || _n2##i==--_n3##i || _n1##i==--_n2##i || i==(_n3##i = _n2##i = --_n1##i); \
923 _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i, ++_n3##i)
924 #define cimg_for6X(img,x) cimg_for6((img)._width,x)
925 #define cimg_for6Y(img,y) cimg_for6((img)._height,y)
926 #define cimg_for6Z(img,z) cimg_for6((img)._depth,z)
927 #define cimg_for6C(img,c) cimg_for6((img)._spectrum,c)
928 #define cimg_for6XY(img,x,y) cimg_for6Y(img,y) cimg_for6X(img,x)
929 #define cimg_for6XZ(img,x,z) cimg_for6Z(img,z) cimg_for6X(img,x)
930 #define cimg_for6XC(img,x,c) cimg_for6C(img,c) cimg_for6X(img,x)
931 #define cimg_for6YZ(img,y,z) cimg_for6Z(img,z) cimg_for6Y(img,y)
932 #define cimg_for6YC(img,y,c) cimg_for6C(img,c) cimg_for6Y(img,y)
933 #define cimg_for6ZC(img,z,c) cimg_for6C(img,c) cimg_for6Z(img,z)
934 #define cimg_for6XYZ(img,x,y,z) cimg_for6Z(img,z) cimg_for6XY(img,x,y)
935 #define cimg_for6XZC(img,x,z,c) cimg_for6C(img,c) cimg_for6XZ(img,x,z)
936 #define cimg_for6YZC(img,y,z,c) cimg_for6C(img,c) cimg_for6YZ(img,y,z)
937 #define cimg_for6XYZC(img,x,y,z,c) cimg_for6C(img,c) cimg_for6XYZ(img,x,y,z)
939 #define cimg_for_in6(bound,i0,i1,i) \
940 for (int i = (int)(i0)<0?0:(int)(i0), \
941 _p2##i = i-2<0?0:i-2, \
942 _p1##i = i-1<0?0:i-1, \
943 _n1##i = i+1>=(int)(bound)?(int)(bound)-1:i+1, \
944 _n2##i = i+2>=(int)(bound)?(int)(bound)-1:i+2, \
945 _n3##i = i+3>=(int)(bound)?(int)(bound)-1:i+3; \
946 i<=(int)(i1) && (_n3##i<(int)(bound) || _n2##i==--_n3##i || _n1##i==--_n2##i || i==(_n3##i = _n2##i = --_n1##i)); \
947 _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i, ++_n3##i)
948 #define cimg_for_in6X(img,x0,x1,x) cimg_for_in6((img)._width,x0,x1,x)
949 #define cimg_for_in6Y(img,y0,y1,y) cimg_for_in6((img)._height,y0,y1,y)
950 #define cimg_for_in6Z(img,z0,z1,z) cimg_for_in6((img)._depth,z0,z1,z)
951 #define cimg_for_in6C(img,c0,c1,c) cimg_for_in6((img)._spectrum,c0,c1,c)
952 #define cimg_for_in6XY(img,x0,y0,x1,y1,x,y) cimg_for_in6Y(img,y0,y1,y) cimg_for_in6X(img,x0,x1,x)
953 #define cimg_for_in6XZ(img,x0,z0,x1,z1,x,z) cimg_for_in6Z(img,z0,z1,z) cimg_for_in6X(img,x0,x1,x)
954 #define cimg_for_in6XC(img,x0,c0,x1,c1,x,c) cimg_for_in6C(img,c0,c1,c) cimg_for_in6X(img,x0,x1,x)
955 #define cimg_for_in6YZ(img,y0,z0,y1,z1,y,z) cimg_for_in6Z(img,z0,z1,z) cimg_for_in6Y(img,y0,y1,y)
956 #define cimg_for_in6YC(img,y0,c0,y1,c1,y,c) cimg_for_in6C(img,c0,c1,c) cimg_for_in6Y(img,y0,y1,y)
957 #define cimg_for_in6ZC(img,z0,c0,z1,c1,z,c) cimg_for_in6C(img,c0,c1,c) cimg_for_in6Z(img,z0,z1,z)
958 #define cimg_for_in6XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in6Z(img,z0,z1,z) cimg_for_in6XY(img,x0,y0,x1,y1,x,y)
959 #define cimg_for_in6XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in6C(img,c0,c1,c) cimg_for_in6XZ(img,x0,y0,x1,y1,x,z)
960 #define cimg_for_in6YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in6C(img,c0,c1,c) cimg_for_in6YZ(img,y0,z0,y1,z1,y,z)
961 #define cimg_for_in6XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_in6C(img,c0,c1,c) cimg_for_in6XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z)
963 #define cimg_for7(bound,i) \
964 for (int i = 0, _p3##i = 0, _p2##i = 0, _p1##i = 0, \
965 _n1##i = 1>=(bound)?(int)(bound)-1:1, \
966 _n2##i = 2>=(bound)?(int)(bound)-1:2, \
967 _n3##i = 3>=(bound)?(int)(bound)-1:3; \
968 _n3##i<(int)(bound) || _n2##i==--_n3##i || _n1##i==--_n2##i || i==(_n3##i = _n2##i = --_n1##i); \
969 _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i, ++_n3##i)
970 #define cimg_for7X(img,x) cimg_for7((img)._width,x)
971 #define cimg_for7Y(img,y) cimg_for7((img)._height,y)
972 #define cimg_for7Z(img,z) cimg_for7((img)._depth,z)
973 #define cimg_for7C(img,c) cimg_for7((img)._spectrum,c)
974 #define cimg_for7XY(img,x,y) cimg_for7Y(img,y) cimg_for7X(img,x)
975 #define cimg_for7XZ(img,x,z) cimg_for7Z(img,z) cimg_for7X(img,x)
976 #define cimg_for7XC(img,x,c) cimg_for7C(img,c) cimg_for7X(img,x)
977 #define cimg_for7YZ(img,y,z) cimg_for7Z(img,z) cimg_for7Y(img,y)
978 #define cimg_for7YC(img,y,c) cimg_for7C(img,c) cimg_for7Y(img,y)
979 #define cimg_for7ZC(img,z,c) cimg_for7C(img,c) cimg_for7Z(img,z)
980 #define cimg_for7XYZ(img,x,y,z) cimg_for7Z(img,z) cimg_for7XY(img,x,y)
981 #define cimg_for7XZC(img,x,z,c) cimg_for7C(img,c) cimg_for7XZ(img,x,z)
982 #define cimg_for7YZC(img,y,z,c) cimg_for7C(img,c) cimg_for7YZ(img,y,z)
983 #define cimg_for7XYZC(img,x,y,z,c) cimg_for7C(img,c) cimg_for7XYZ(img,x,y,z)
985 #define cimg_for_in7(bound,i0,i1,i) \
986 for (int i = (int)(i0)<0?0:(int)(i0), \
987 _p3##i = i-3<0?0:i-3, \
988 _p2##i = i-2<0?0:i-2, \
989 _p1##i = i-1<0?0:i-1, \
990 _n1##i = i+1>=(int)(bound)?(int)(bound)-1:i+1, \
991 _n2##i = i+2>=(int)(bound)?(int)(bound)-1:i+2, \
992 _n3##i = i+3>=(int)(bound)?(int)(bound)-1:i+3; \
993 i<=(int)(i1) && (_n3##i<(int)(bound) || _n2##i==--_n3##i || _n1##i==--_n2##i || i==(_n3##i = _n2##i = --_n1##i)); \
994 _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i, ++_n3##i)
995 #define cimg_for_in7X(img,x0,x1,x) cimg_for_in7((img)._width,x0,x1,x)
996 #define cimg_for_in7Y(img,y0,y1,y) cimg_for_in7((img)._height,y0,y1,y)
997 #define cimg_for_in7Z(img,z0,z1,z) cimg_for_in7((img)._depth,z0,z1,z)
998 #define cimg_for_in7C(img,c0,c1,c) cimg_for_in7((img)._spectrum,c0,c1,c)
999 #define cimg_for_in7XY(img,x0,y0,x1,y1,x,y) cimg_for_in7Y(img,y0,y1,y) cimg_for_in7X(img,x0,x1,x)
1000 #define cimg_for_in7XZ(img,x0,z0,x1,z1,x,z) cimg_for_in7Z(img,z0,z1,z) cimg_for_in7X(img,x0,x1,x)
1001 #define cimg_for_in7XC(img,x0,c0,x1,c1,x,c) cimg_for_in7C(img,c0,c1,c) cimg_for_in7X(img,x0,x1,x)
1002 #define cimg_for_in7YZ(img,y0,z0,y1,z1,y,z) cimg_for_in7Z(img,z0,z1,z) cimg_for_in7Y(img,y0,y1,y)
1003 #define cimg_for_in7YC(img,y0,c0,y1,c1,y,c) cimg_for_in7C(img,c0,c1,c) cimg_for_in7Y(img,y0,y1,y)
1004 #define cimg_for_in7ZC(img,z0,c0,z1,c1,z,c) cimg_for_in7C(img,c0,c1,c) cimg_for_in7Z(img,z0,z1,z)
1005 #define cimg_for_in7XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in7Z(img,z0,z1,z) cimg_for_in7XY(img,x0,y0,x1,y1,x,y)
1006 #define cimg_for_in7XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in7C(img,c0,c1,c) cimg_for_in7XZ(img,x0,y0,x1,y1,x,z)
1007 #define cimg_for_in7YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in7C(img,c0,c1,c) cimg_for_in7YZ(img,y0,z0,y1,z1,y,z)
1008 #define cimg_for_in7XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_in7C(img,c0,c1,c) cimg_for_in7XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z)
1010 #define cimg_for8(bound,i) \
1011 for (int i = 0, _p3##i = 0, _p2##i = 0, _p1##i = 0, \
1012 _n1##i = 1>=(bound)?(int)(bound)-1:1, \
1013 _n2##i = 2>=(bound)?(int)(bound)-1:2, \
1014 _n3##i = 3>=(bound)?(int)(bound)-1:3, \
1015 _n4##i = 4>=(bound)?(int)(bound)-1:4; \
1016 _n4##i<(int)(bound) || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \
1017 i==(_n4##i = _n3##i = _n2##i = --_n1##i); \
1018 _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i)
1019 #define cimg_for8X(img,x) cimg_for8((img)._width,x)
1020 #define cimg_for8Y(img,y) cimg_for8((img)._height,y)
1021 #define cimg_for8Z(img,z) cimg_for8((img)._depth,z)
1022 #define cimg_for8C(img,c) cimg_for8((img)._spectrum,c)
1023 #define cimg_for8XY(img,x,y) cimg_for8Y(img,y) cimg_for8X(img,x)
1024 #define cimg_for8XZ(img,x,z) cimg_for8Z(img,z) cimg_for8X(img,x)
1025 #define cimg_for8XC(img,x,c) cimg_for8C(img,c) cimg_for8X(img,x)
1026 #define cimg_for8YZ(img,y,z) cimg_for8Z(img,z) cimg_for8Y(img,y)
1027 #define cimg_for8YC(img,y,c) cimg_for8C(img,c) cimg_for8Y(img,y)
1028 #define cimg_for8ZC(img,z,c) cimg_for8C(img,c) cimg_for8Z(img,z)
1029 #define cimg_for8XYZ(img,x,y,z) cimg_for8Z(img,z) cimg_for8XY(img,x,y)
1030 #define cimg_for8XZC(img,x,z,c) cimg_for8C(img,c) cimg_for8XZ(img,x,z)
1031 #define cimg_for8YZC(img,y,z,c) cimg_for8C(img,c) cimg_for8YZ(img,y,z)
1032 #define cimg_for8XYZC(img,x,y,z,c) cimg_for8C(img,c) cimg_for8XYZ(img,x,y,z)
1034 #define cimg_for_in8(bound,i0,i1,i) \
1035 for (int i = (int)(i0)<0?0:(int)(i0), \
1036 _p3##i = i-3<0?0:i-3, \
1037 _p2##i = i-2<0?0:i-2, \
1038 _p1##i = i-1<0?0:i-1, \
1039 _n1##i = i+1>=(int)(bound)?(int)(bound)-1:i+1, \
1040 _n2##i = i+2>=(int)(bound)?(int)(bound)-1:i+2, \
1041 _n3##i = i+3>=(int)(bound)?(int)(bound)-1:i+3, \
1042 _n4##i = i+4>=(int)(bound)?(int)(bound)-1:i+4; \
1043 i<=(int)(i1) && (_n4##i<(int)(bound) || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \
1044 i==(_n4##i = _n3##i = _n2##i = --_n1##i)); \
1045 _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i)
1046 #define cimg_for_in8X(img,x0,x1,x) cimg_for_in8((img)._width,x0,x1,x)
1047 #define cimg_for_in8Y(img,y0,y1,y) cimg_for_in8((img)._height,y0,y1,y)
1048 #define cimg_for_in8Z(img,z0,z1,z) cimg_for_in8((img)._depth,z0,z1,z)
1049 #define cimg_for_in8C(img,c0,c1,c) cimg_for_in8((img)._spectrum,c0,c1,c)
1050 #define cimg_for_in8XY(img,x0,y0,x1,y1,x,y) cimg_for_in8Y(img,y0,y1,y) cimg_for_in8X(img,x0,x1,x)
1051 #define cimg_for_in8XZ(img,x0,z0,x1,z1,x,z) cimg_for_in8Z(img,z0,z1,z) cimg_for_in8X(img,x0,x1,x)
1052 #define cimg_for_in8XC(img,x0,c0,x1,c1,x,c) cimg_for_in8C(img,c0,c1,c) cimg_for_in8X(img,x0,x1,x)
1053 #define cimg_for_in8YZ(img,y0,z0,y1,z1,y,z) cimg_for_in8Z(img,z0,z1,z) cimg_for_in8Y(img,y0,y1,y)
1054 #define cimg_for_in8YC(img,y0,c0,y1,c1,y,c) cimg_for_in8C(img,c0,c1,c) cimg_for_in8Y(img,y0,y1,y)
1055 #define cimg_for_in8ZC(img,z0,c0,z1,c1,z,c) cimg_for_in8C(img,c0,c1,c) cimg_for_in8Z(img,z0,z1,z)
1056 #define cimg_for_in8XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in8Z(img,z0,z1,z) cimg_for_in8XY(img,x0,y0,x1,y1,x,y)
1057 #define cimg_for_in8XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in8C(img,c0,c1,c) cimg_for_in8XZ(img,x0,y0,x1,y1,x,z)
1058 #define cimg_for_in8YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in8C(img,c0,c1,c) cimg_for_in8YZ(img,y0,z0,y1,z1,y,z)
1059 #define cimg_for_in8XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_in8C(img,c0,c1,c) cimg_for_in8XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z)
1061 #define cimg_for9(bound,i) \
1062 for (int i = 0, _p4##i = 0, _p3##i = 0, _p2##i = 0, _p1##i = 0, \
1063 _n1##i = 1>=(int)(bound)?(int)(bound)-1:1, \
1064 _n2##i = 2>=(int)(bound)?(int)(bound)-1:2, \
1065 _n3##i = 3>=(int)(bound)?(int)(bound)-1:3, \
1066 _n4##i = 4>=(int)(bound)?(int)(bound)-1:4; \
1067 _n4##i<(int)(bound) || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \
1068 i==(_n4##i = _n3##i = _n2##i = --_n1##i); \
1069 _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i)
1070 #define cimg_for9X(img,x) cimg_for9((img)._width,x)
1071 #define cimg_for9Y(img,y) cimg_for9((img)._height,y)
1072 #define cimg_for9Z(img,z) cimg_for9((img)._depth,z)
1073 #define cimg_for9C(img,c) cimg_for9((img)._spectrum,c)
1074 #define cimg_for9XY(img,x,y) cimg_for9Y(img,y) cimg_for9X(img,x)
1075 #define cimg_for9XZ(img,x,z) cimg_for9Z(img,z) cimg_for9X(img,x)
1076 #define cimg_for9XC(img,x,c) cimg_for9C(img,c) cimg_for9X(img,x)
1077 #define cimg_for9YZ(img,y,z) cimg_for9Z(img,z) cimg_for9Y(img,y)
1078 #define cimg_for9YC(img,y,c) cimg_for9C(img,c) cimg_for9Y(img,y)
1079 #define cimg_for9ZC(img,z,c) cimg_for9C(img,c) cimg_for9Z(img,z)
1080 #define cimg_for9XYZ(img,x,y,z) cimg_for9Z(img,z) cimg_for9XY(img,x,y)
1081 #define cimg_for9XZC(img,x,z,c) cimg_for9C(img,c) cimg_for9XZ(img,x,z)
1082 #define cimg_for9YZC(img,y,z,c) cimg_for9C(img,c) cimg_for9YZ(img,y,z)
1083 #define cimg_for9XYZC(img,x,y,z,c) cimg_for9C(img,c) cimg_for9XYZ(img,x,y,z)
1085 #define cimg_for_in9(bound,i0,i1,i) \
1086 for (int i = (int)(i0)<0?0:(int)(i0), \
1087 _p4##i = i-4<0?0:i-4, \
1088 _p3##i = i-3<0?0:i-3, \
1089 _p2##i = i-2<0?0:i-2, \
1090 _p1##i = i-1<0?0:i-1, \
1091 _n1##i = i+1>=(int)(bound)?(int)(bound)-1:i+1, \
1092 _n2##i = i+2>=(int)(bound)?(int)(bound)-1:i+2, \
1093 _n3##i = i+3>=(int)(bound)?(int)(bound)-1:i+3, \
1094 _n4##i = i+4>=(int)(bound)?(int)(bound)-1:i+4; \
1095 i<=(int)(i1) && (_n4##i<(int)(bound) || _n3##i==--_n4##i || _n2##i==--_n3##i || _n1##i==--_n2##i || \
1096 i==(_n4##i = _n3##i = _n2##i = --_n1##i)); \
1097 _p4##i = _p3##i, _p3##i = _p2##i, _p2##i = _p1##i, _p1##i = i++, ++_n1##i, ++_n2##i, ++_n3##i, ++_n4##i)
1098 #define cimg_for_in9X(img,x0,x1,x) cimg_for_in9((img)._width,x0,x1,x)
1099 #define cimg_for_in9Y(img,y0,y1,y) cimg_for_in9((img)._height,y0,y1,y)
1100 #define cimg_for_in9Z(img,z0,z1,z) cimg_for_in9((img)._depth,z0,z1,z)
1101 #define cimg_for_in9C(img,c0,c1,c) cimg_for_in9((img)._spectrum,c0,c1,c)
1102 #define cimg_for_in9XY(img,x0,y0,x1,y1,x,y) cimg_for_in9Y(img,y0,y1,y) cimg_for_in9X(img,x0,x1,x)
1103 #define cimg_for_in9XZ(img,x0,z0,x1,z1,x,z) cimg_for_in9Z(img,z0,z1,z) cimg_for_in9X(img,x0,x1,x)
1104 #define cimg_for_in9XC(img,x0,c0,x1,c1,x,c) cimg_for_in9C(img,c0,c1,c) cimg_for_in9X(img,x0,x1,x)
1105 #define cimg_for_in9YZ(img,y0,z0,y1,z1,y,z) cimg_for_in9Z(img,z0,z1,z) cimg_for_in9Y(img,y0,y1,y)
1106 #define cimg_for_in9YC(img,y0,c0,y1,c1,y,c) cimg_for_in9C(img,c0,c1,c) cimg_for_in9Y(img,y0,y1,y)
1107 #define cimg_for_in9ZC(img,z0,c0,z1,c1,z,c) cimg_for_in9C(img,c0,c1,c) cimg_for_in9Z(img,z0,z1,z)
1108 #define cimg_for_in9XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z) cimg_for_in9Z(img,z0,z1,z) cimg_for_in9XY(img,x0,y0,x1,y1,x,y)
1109 #define cimg_for_in9XZC(img,x0,z0,c0,x1,y1,c1,x,z,c) cimg_for_in9C(img,c0,c1,c) cimg_for_in9XZ(img,x0,y0,x1,y1,x,z)
1110 #define cimg_for_in9YZC(img,y0,z0,c0,y1,z1,c1,y,z,c) cimg_for_in9C(img,c0,c1,c) cimg_for_in9YZ(img,y0,z0,y1,z1,y,z)
1111 #define cimg_for_in9XYZC(img,x0,y0,z0,c0,x1,y1,z1,c1,x,y,z,c) cimg_for_in9C(img,c0,c1,c) cimg_for_in9XYZ(img,x0,y0,z0,x1,y1,z1,x,y,z)
1113 #define cimg_for2x2(img,x,y,z,c,I,T) \
1114 cimg_for2((img)._height,y) for (int x = 0, \
1116 (I[0] = (T)(img)(0,y,z,c)), \
1117 (I[2] = (T)(img)(0,_n1##y,z,c)), \
1118 1>=(img)._width?(img).width()-1:1); \
1119 (_n1##x<(img).width() && ( \
1120 (I[1] = (T)(img)(_n1##x,y,z,c)), \
1121 (I[3] = (T)(img)(_n1##x,_n1##y,z,c)),1)) || \
1127 #define cimg_for_in2x2(img,x0,y0,x1,y1,x,y,z,c,I,T) \
1128 cimg_for_in2((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \
1130 (I[0] = (T)(img)(x,y,z,c)), \
1131 (I[2] = (T)(img)(x,_n1##y,z,c)), \
1132 x+1>=(int)(img)._width?(img).width()-1:x+1); \
1133 x<=(int)(x1) && ((_n1##x<(img).width() && ( \
1134 (I[1] = (T)(img)(_n1##x,y,z,c)), \
1135 (I[3] = (T)(img)(_n1##x,_n1##y,z,c)),1)) || \
1141 #define cimg_for3x3(img,x,y,z,c,I,T) \
1142 cimg_for3((img)._height,y) for (int x = 0, \
1145 (I[0] = I[1] = (T)(img)(_p1##x,_p1##y,z,c)), \
1146 (I[3] = I[4] = (T)(img)(0,y,z,c)), \
1147 (I[6] = I[7] = (T)(img)(0,_n1##y,z,c)), \
1148 1>=(img)._width?(img).width()-1:1); \
1149 (_n1##x<(img).width() && ( \
1150 (I[2] = (T)(img)(_n1##x,_p1##y,z,c)), \
1151 (I[5] = (T)(img)(_n1##x,y,z,c)), \
1152 (I[8] = (T)(img)(_n1##x,_n1##y,z,c)),1)) || \
1154 I[0] = I[1], I[1] = I[2], \
1155 I[3] = I[4], I[4] = I[5], \
1156 I[6] = I[7], I[7] = I[8], \
1157 _p1##x = x++, ++_n1##x)
1159 #define cimg_for_in3x3(img,x0,y0,x1,y1,x,y,z,c,I,T) \
1160 cimg_for_in3((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \
1161 _p1##x = x-1<0?0:x-1, \
1163 (I[0] = (T)(img)(_p1##x,_p1##y,z,c)), \
1164 (I[3] = (T)(img)(_p1##x,y,z,c)), \
1165 (I[6] = (T)(img)(_p1##x,_n1##y,z,c)), \
1166 (I[1] = (T)(img)(x,_p1##y,z,c)), \
1167 (I[4] = (T)(img)(x,y,z,c)), \
1168 (I[7] = (T)(img)(x,_n1##y,z,c)), \
1169 x+1>=(int)(img)._width?(img).width()-1:x+1); \
1170 x<=(int)(x1) && ((_n1##x<(img).width() && ( \
1171 (I[2] = (T)(img)(_n1##x,_p1##y,z,c)), \
1172 (I[5] = (T)(img)(_n1##x,y,z,c)), \
1173 (I[8] = (T)(img)(_n1##x,_n1##y,z,c)),1)) || \
1175 I[0] = I[1], I[1] = I[2], \
1176 I[3] = I[4], I[4] = I[5], \
1177 I[6] = I[7], I[7] = I[8], \
1178 _p1##x = x++, ++_n1##x)
1180 #define cimg_for4x4(img,x,y,z,c,I,T) \
1181 cimg_for4((img)._height,y) for (int x = 0, \
1183 _n1##x = 1>=(img)._width?(img).width()-1:1, \
1185 (I[0] = I[1] = (T)(img)(_p1##x,_p1##y,z,c)), \
1186 (I[4] = I[5] = (T)(img)(0,y,z,c)), \
1187 (I[8] = I[9] = (T)(img)(0,_n1##y,z,c)), \
1188 (I[12] = I[13] = (T)(img)(0,_n2##y,z,c)), \
1189 (I[2] = (T)(img)(_n1##x,_p1##y,z,c)), \
1190 (I[6] = (T)(img)(_n1##x,y,z,c)), \
1191 (I[10] = (T)(img)(_n1##x,_n1##y,z,c)), \
1192 (I[14] = (T)(img)(_n1##x,_n2##y,z,c)), \
1193 2>=(img)._width?(img).width()-1:2); \
1194 (_n2##x<(img).width() && ( \
1195 (I[3] = (T)(img)(_n2##x,_p1##y,z,c)), \
1196 (I[7] = (T)(img)(_n2##x,y,z,c)), \
1197 (I[11] = (T)(img)(_n2##x,_n1##y,z,c)), \
1198 (I[15] = (T)(img)(_n2##x,_n2##y,z,c)),1)) || \
1199 _n1##x==--_n2##x || x==(_n2##x = --_n1##x); \
1200 I[0] = I[1], I[1] = I[2], I[2] = I[3], \
1201 I[4] = I[5], I[5] = I[6], I[6] = I[7], \
1202 I[8] = I[9], I[9] = I[10], I[10] = I[11], \
1203 I[12] = I[13], I[13] = I[14], I[14] = I[15], \
1204 _p1##x = x++, ++_n1##x, ++_n2##x)
1206 #define cimg_for_in4x4(img,x0,y0,x1,y1,x,y,z,c,I,T) \
1207 cimg_for_in4((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \
1208 _p1##x = x-1<0?0:x-1, \
1209 _n1##x = x+1>=(int)(img)._width?(img).width()-1:x+1, \
1211 (I[0] = (T)(img)(_p1##x,_p1##y,z,c)), \
1212 (I[4] = (T)(img)(_p1##x,y,z,c)), \
1213 (I[8] = (T)(img)(_p1##x,_n1##y,z,c)), \
1214 (I[12] = (T)(img)(_p1##x,_n2##y,z,c)), \
1215 (I[1] = (T)(img)(x,_p1##y,z,c)), \
1216 (I[5] = (T)(img)(x,y,z,c)), \
1217 (I[9] = (T)(img)(x,_n1##y,z,c)), \
1218 (I[13] = (T)(img)(x,_n2##y,z,c)), \
1219 (I[2] = (T)(img)(_n1##x,_p1##y,z,c)), \
1220 (I[6] = (T)(img)(_n1##x,y,z,c)), \
1221 (I[10] = (T)(img)(_n1##x,_n1##y,z,c)), \
1222 (I[14] = (T)(img)(_n1##x,_n2##y,z,c)), \
1223 x+2>=(int)(img)._width?(img).width()-1:x+2); \
1224 x<=(int)(x1) && ((_n2##x<(img).width() && ( \
1225 (I[3] = (T)(img)(_n2##x,_p1##y,z,c)), \
1226 (I[7] = (T)(img)(_n2##x,y,z,c)), \
1227 (I[11] = (T)(img)(_n2##x,_n1##y,z,c)), \
1228 (I[15] = (T)(img)(_n2##x,_n2##y,z,c)),1)) || \
1229 _n1##x==--_n2##x || x==(_n2##x = --_n1##x)); \
1230 I[0] = I[1], I[1] = I[2], I[2] = I[3], \
1231 I[4] = I[5], I[5] = I[6], I[6] = I[7], \
1232 I[8] = I[9], I[9] = I[10], I[10] = I[11], \
1233 I[12] = I[13], I[13] = I[14], I[14] = I[15], \
1234 _p1##x = x++, ++_n1##x, ++_n2##x)
1236 #define cimg_for5x5(img,x,y,z,c,I,T) \
1237 cimg_for5((img)._height,y) for (int x = 0, \
1238 _p2##x = 0, _p1##x = 0, \
1239 _n1##x = 1>=(img)._width?(img).width()-1:1, \
1241 (I[0] = I[1] = I[2] = (T)(img)(_p2##x,_p2##y,z,c)), \
1242 (I[5] = I[6] = I[7] = (T)(img)(0,_p1##y,z,c)), \
1243 (I[10] = I[11] = I[12] = (T)(img)(0,y,z,c)), \
1244 (I[15] = I[16] = I[17] = (T)(img)(0,_n1##y,z,c)), \
1245 (I[20] = I[21] = I[22] = (T)(img)(0,_n2##y,z,c)), \
1246 (I[3] = (T)(img)(_n1##x,_p2##y,z,c)), \
1247 (I[8] = (T)(img)(_n1##x,_p1##y,z,c)), \
1248 (I[13] = (T)(img)(_n1##x,y,z,c)), \
1249 (I[18] = (T)(img)(_n1##x,_n1##y,z,c)), \
1250 (I[23] = (T)(img)(_n1##x,_n2##y,z,c)), \
1251 2>=(img)._width?(img).width()-1:2); \
1252 (_n2##x<(img).width() && ( \
1253 (I[4] = (T)(img)(_n2##x,_p2##y,z,c)), \
1254 (I[9] = (T)(img)(_n2##x,_p1##y,z,c)), \
1255 (I[14] = (T)(img)(_n2##x,y,z,c)), \
1256 (I[19] = (T)(img)(_n2##x,_n1##y,z,c)), \
1257 (I[24] = (T)(img)(_n2##x,_n2##y,z,c)),1)) || \
1258 _n1##x==--_n2##x || x==(_n2##x = --_n1##x); \
1259 I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], \
1260 I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], \
1261 I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], \
1262 I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], \
1263 I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], \
1264 _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x)
1266 #define cimg_for_in5x5(img,x0,y0,x1,y1,x,y,z,c,I,T) \
1267 cimg_for_in5((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \
1268 _p2##x = x-2<0?0:x-2, \
1269 _p1##x = x-1<0?0:x-1, \
1270 _n1##x = x+1>=(int)(img)._width?(img).width()-1:x+1, \
1272 (I[0] = (T)(img)(_p2##x,_p2##y,z,c)), \
1273 (I[5] = (T)(img)(_p2##x,_p1##y,z,c)), \
1274 (I[10] = (T)(img)(_p2##x,y,z,c)), \
1275 (I[15] = (T)(img)(_p2##x,_n1##y,z,c)), \
1276 (I[20] = (T)(img)(_p2##x,_n2##y,z,c)), \
1277 (I[1] = (T)(img)(_p1##x,_p2##y,z,c)), \
1278 (I[6] = (T)(img)(_p1##x,_p1##y,z,c)), \
1279 (I[11] = (T)(img)(_p1##x,y,z,c)), \
1280 (I[16] = (T)(img)(_p1##x,_n1##y,z,c)), \
1281 (I[21] = (T)(img)(_p1##x,_n2##y,z,c)), \
1282 (I[2] = (T)(img)(x,_p2##y,z,c)), \
1283 (I[7] = (T)(img)(x,_p1##y,z,c)), \
1284 (I[12] = (T)(img)(x,y,z,c)), \
1285 (I[17] = (T)(img)(x,_n1##y,z,c)), \
1286 (I[22] = (T)(img)(x,_n2##y,z,c)), \
1287 (I[3] = (T)(img)(_n1##x,_p2##y,z,c)), \
1288 (I[8] = (T)(img)(_n1##x,_p1##y,z,c)), \
1289 (I[13] = (T)(img)(_n1##x,y,z,c)), \
1290 (I[18] = (T)(img)(_n1##x,_n1##y,z,c)), \
1291 (I[23] = (T)(img)(_n1##x,_n2##y,z,c)), \
1292 x+2>=(int)(img)._width?(img).width()-1:x+2); \
1293 x<=(int)(x1) && ((_n2##x<(img).width() && ( \
1294 (I[4] = (T)(img)(_n2##x,_p2##y,z,c)), \
1295 (I[9] = (T)(img)(_n2##x,_p1##y,z,c)), \
1296 (I[14] = (T)(img)(_n2##x,y,z,c)), \
1297 (I[19] = (T)(img)(_n2##x,_n1##y,z,c)), \
1298 (I[24] = (T)(img)(_n2##x,_n2##y,z,c)),1)) || \
1299 _n1##x==--_n2##x || x==(_n2##x = --_n1##x)); \
1300 I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], \
1301 I[5] = I[6], I[6] = I[7], I[7] = I[8], I[8] = I[9], \
1302 I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], \
1303 I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], \
1304 I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], \
1305 _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x)
1307 #define cimg_for6x6(img,x,y,z,c,I,T) \
1308 cimg_for6((img)._height,y) for (int x = 0, \
1309 _p2##x = 0, _p1##x = 0, \
1310 _n1##x = 1>=(img)._width?(img).width()-1:1, \
1311 _n2##x = 2>=(img)._width?(img).width()-1:2, \
1313 (I[0] = I[1] = I[2] = (T)(img)(_p2##x,_p2##y,z,c)), \
1314 (I[6] = I[7] = I[8] = (T)(img)(0,_p1##y,z,c)), \
1315 (I[12] = I[13] = I[14] = (T)(img)(0,y,z,c)), \
1316 (I[18] = I[19] = I[20] = (T)(img)(0,_n1##y,z,c)), \
1317 (I[24] = I[25] = I[26] = (T)(img)(0,_n2##y,z,c)), \
1318 (I[30] = I[31] = I[32] = (T)(img)(0,_n3##y,z,c)), \
1319 (I[3] = (T)(img)(_n1##x,_p2##y,z,c)), \
1320 (I[9] = (T)(img)(_n1##x,_p1##y,z,c)), \
1321 (I[15] = (T)(img)(_n1##x,y,z,c)), \
1322 (I[21] = (T)(img)(_n1##x,_n1##y,z,c)), \
1323 (I[27] = (T)(img)(_n1##x,_n2##y,z,c)), \
1324 (I[33] = (T)(img)(_n1##x,_n3##y,z,c)), \
1325 (I[4] = (T)(img)(_n2##x,_p2##y,z,c)), \
1326 (I[10] = (T)(img)(_n2##x,_p1##y,z,c)), \
1327 (I[16] = (T)(img)(_n2##x,y,z,c)), \
1328 (I[22] = (T)(img)(_n2##x,_n1##y,z,c)), \
1329 (I[28] = (T)(img)(_n2##x,_n2##y,z,c)), \
1330 (I[34] = (T)(img)(_n2##x,_n3##y,z,c)), \
1331 3>=(img)._width?(img).width()-1:3); \
1332 (_n3##x<(img).width() && ( \
1333 (I[5] = (T)(img)(_n3##x,_p2##y,z,c)), \
1334 (I[11] = (T)(img)(_n3##x,_p1##y,z,c)), \
1335 (I[17] = (T)(img)(_n3##x,y,z,c)), \
1336 (I[23] = (T)(img)(_n3##x,_n1##y,z,c)), \
1337 (I[29] = (T)(img)(_n3##x,_n2##y,z,c)), \
1338 (I[35] = (T)(img)(_n3##x,_n3##y,z,c)),1)) || \
1339 _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n3## x = _n2##x = --_n1##x); \
1340 I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], \
1341 I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], \
1342 I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], \
1343 I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], \
1344 I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], \
1345 I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], \
1346 _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x)
1348 #define cimg_for_in6x6(img,x0,y0,x1,y1,x,y,z,c,I,T) \
1349 cimg_for_in6((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)x0, \
1350 _p2##x = x-2<0?0:x-2, \
1351 _p1##x = x-1<0?0:x-1, \
1352 _n1##x = x+1>=(int)(img)._width?(img).width()-1:x+1, \
1353 _n2##x = x+2>=(int)(img)._width?(img).width()-1:x+2, \
1355 (I[0] = (T)(img)(_p2##x,_p2##y,z,c)), \
1356 (I[6] = (T)(img)(_p2##x,_p1##y,z,c)), \
1357 (I[12] = (T)(img)(_p2##x,y,z,c)), \
1358 (I[18] = (T)(img)(_p2##x,_n1##y,z,c)), \
1359 (I[24] = (T)(img)(_p2##x,_n2##y,z,c)), \
1360 (I[30] = (T)(img)(_p2##x,_n3##y,z,c)), \
1361 (I[1] = (T)(img)(_p1##x,_p2##y,z,c)), \
1362 (I[7] = (T)(img)(_p1##x,_p1##y,z,c)), \
1363 (I[13] = (T)(img)(_p1##x,y,z,c)), \
1364 (I[19] = (T)(img)(_p1##x,_n1##y,z,c)), \
1365 (I[25] = (T)(img)(_p1##x,_n2##y,z,c)), \
1366 (I[31] = (T)(img)(_p1##x,_n3##y,z,c)), \
1367 (I[2] = (T)(img)(x,_p2##y,z,c)), \
1368 (I[8] = (T)(img)(x,_p1##y,z,c)), \
1369 (I[14] = (T)(img)(x,y,z,c)), \
1370 (I[20] = (T)(img)(x,_n1##y,z,c)), \
1371 (I[26] = (T)(img)(x,_n2##y,z,c)), \
1372 (I[32] = (T)(img)(x,_n3##y,z,c)), \
1373 (I[3] = (T)(img)(_n1##x,_p2##y,z,c)), \
1374 (I[9] = (T)(img)(_n1##x,_p1##y,z,c)), \
1375 (I[15] = (T)(img)(_n1##x,y,z,c)), \
1376 (I[21] = (T)(img)(_n1##x,_n1##y,z,c)), \
1377 (I[27] = (T)(img)(_n1##x,_n2##y,z,c)), \
1378 (I[33] = (T)(img)(_n1##x,_n3##y,z,c)), \
1379 (I[4] = (T)(img)(_n2##x,_p2##y,z,c)), \
1380 (I[10] = (T)(img)(_n2##x,_p1##y,z,c)), \
1381 (I[16] = (T)(img)(_n2##x,y,z,c)), \
1382 (I[22] = (T)(img)(_n2##x,_n1##y,z,c)), \
1383 (I[28] = (T)(img)(_n2##x,_n2##y,z,c)), \
1384 (I[34] = (T)(img)(_n2##x,_n3##y,z,c)), \
1385 x+3>=(int)(img)._width?(img).width()-1:x+3); \
1386 x<=(int)(x1) && ((_n3##x<(img).width() && ( \
1387 (I[5] = (T)(img)(_n3##x,_p2##y,z,c)), \
1388 (I[11] = (T)(img)(_n3##x,_p1##y,z,c)), \
1389 (I[17] = (T)(img)(_n3##x,y,z,c)), \
1390 (I[23] = (T)(img)(_n3##x,_n1##y,z,c)), \
1391 (I[29] = (T)(img)(_n3##x,_n2##y,z,c)), \
1392 (I[35] = (T)(img)(_n3##x,_n3##y,z,c)),1)) || \
1393 _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n3## x = _n2##x = --_n1##x)); \
1394 I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], \
1395 I[6] = I[7], I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], \
1396 I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], \
1397 I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], \
1398 I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], \
1399 I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], \
1400 _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x)
1402 #define cimg_for7x7(img,x,y,z,c,I,T) \
1403 cimg_for7((img)._height,y) for (int x = 0, \
1404 _p3##x = 0, _p2##x = 0, _p1##x = 0, \
1405 _n1##x = 1>=(img)._width?(img).width()-1:1, \
1406 _n2##x = 2>=(img)._width?(img).width()-1:2, \
1408 (I[0] = I[1] = I[2] = I[3] = (T)(img)(_p3##x,_p3##y,z,c)), \
1409 (I[7] = I[8] = I[9] = I[10] = (T)(img)(0,_p2##y,z,c)), \
1410 (I[14] = I[15] = I[16] = I[17] = (T)(img)(0,_p1##y,z,c)), \
1411 (I[21] = I[22] = I[23] = I[24] = (T)(img)(0,y,z,c)), \
1412 (I[28] = I[29] = I[30] = I[31] = (T)(img)(0,_n1##y,z,c)), \
1413 (I[35] = I[36] = I[37] = I[38] = (T)(img)(0,_n2##y,z,c)), \
1414 (I[42] = I[43] = I[44] = I[45] = (T)(img)(0,_n3##y,z,c)), \
1415 (I[4] = (T)(img)(_n1##x,_p3##y,z,c)), \
1416 (I[11] = (T)(img)(_n1##x,_p2##y,z,c)), \
1417 (I[18] = (T)(img)(_n1##x,_p1##y,z,c)), \
1418 (I[25] = (T)(img)(_n1##x,y,z,c)), \
1419 (I[32] = (T)(img)(_n1##x,_n1##y,z,c)), \
1420 (I[39] = (T)(img)(_n1##x,_n2##y,z,c)), \
1421 (I[46] = (T)(img)(_n1##x,_n3##y,z,c)), \
1422 (I[5] = (T)(img)(_n2##x,_p3##y,z,c)), \
1423 (I[12] = (T)(img)(_n2##x,_p2##y,z,c)), \
1424 (I[19] = (T)(img)(_n2##x,_p1##y,z,c)), \
1425 (I[26] = (T)(img)(_n2##x,y,z,c)), \
1426 (I[33] = (T)(img)(_n2##x,_n1##y,z,c)), \
1427 (I[40] = (T)(img)(_n2##x,_n2##y,z,c)), \
1428 (I[47] = (T)(img)(_n2##x,_n3##y,z,c)), \
1429 3>=(img)._width?(img).width()-1:3); \
1430 (_n3##x<(img).width() && ( \
1431 (I[6] = (T)(img)(_n3##x,_p3##y,z,c)), \
1432 (I[13] = (T)(img)(_n3##x,_p2##y,z,c)), \
1433 (I[20] = (T)(img)(_n3##x,_p1##y,z,c)), \
1434 (I[27] = (T)(img)(_n3##x,y,z,c)), \
1435 (I[34] = (T)(img)(_n3##x,_n1##y,z,c)), \
1436 (I[41] = (T)(img)(_n3##x,_n2##y,z,c)), \
1437 (I[48] = (T)(img)(_n3##x,_n3##y,z,c)),1)) || \
1438 _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n3##x = _n2##x = --_n1##x); \
1439 I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], \
1440 I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], \
1441 I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], \
1442 I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], \
1443 I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], \
1444 I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], \
1445 I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], \
1446 _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x)
1448 #define cimg_for_in7x7(img,x0,y0,x1,y1,x,y,z,c,I,T) \
1449 cimg_for_in7((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \
1450 _p3##x = x-3<0?0:x-3, \
1451 _p2##x = x-2<0?0:x-2, \
1452 _p1##x = x-1<0?0:x-1, \
1453 _n1##x = x+1>=(int)(img)._width?(img).width()-1:x+1, \
1454 _n2##x = x+2>=(int)(img)._width?(img).width()-1:x+2, \
1456 (I[0] = (T)(img)(_p3##x,_p3##y,z,c)), \
1457 (I[7] = (T)(img)(_p3##x,_p2##y,z,c)), \
1458 (I[14] = (T)(img)(_p3##x,_p1##y,z,c)), \
1459 (I[21] = (T)(img)(_p3##x,y,z,c)), \
1460 (I[28] = (T)(img)(_p3##x,_n1##y,z,c)), \
1461 (I[35] = (T)(img)(_p3##x,_n2##y,z,c)), \
1462 (I[42] = (T)(img)(_p3##x,_n3##y,z,c)), \
1463 (I[1] = (T)(img)(_p2##x,_p3##y,z,c)), \
1464 (I[8] = (T)(img)(_p2##x,_p2##y,z,c)), \
1465 (I[15] = (T)(img)(_p2##x,_p1##y,z,c)), \
1466 (I[22] = (T)(img)(_p2##x,y,z,c)), \
1467 (I[29] = (T)(img)(_p2##x,_n1##y,z,c)), \
1468 (I[36] = (T)(img)(_p2##x,_n2##y,z,c)), \
1469 (I[43] = (T)(img)(_p2##x,_n3##y,z,c)), \
1470 (I[2] = (T)(img)(_p1##x,_p3##y,z,c)), \
1471 (I[9] = (T)(img)(_p1##x,_p2##y,z,c)), \
1472 (I[16] = (T)(img)(_p1##x,_p1##y,z,c)), \
1473 (I[23] = (T)(img)(_p1##x,y,z,c)), \
1474 (I[30] = (T)(img)(_p1##x,_n1##y,z,c)), \
1475 (I[37] = (T)(img)(_p1##x,_n2##y,z,c)), \
1476 (I[44] = (T)(img)(_p1##x,_n3##y,z,c)), \
1477 (I[3] = (T)(img)(x,_p3##y,z,c)), \
1478 (I[10] = (T)(img)(x,_p2##y,z,c)), \
1479 (I[17] = (T)(img)(x,_p1##y,z,c)), \
1480 (I[24] = (T)(img)(x,y,z,c)), \
1481 (I[31] = (T)(img)(x,_n1##y,z,c)), \
1482 (I[38] = (T)(img)(x,_n2##y,z,c)), \
1483 (I[45] = (T)(img)(x,_n3##y,z,c)), \
1484 (I[4] = (T)(img)(_n1##x,_p3##y,z,c)), \
1485 (I[11] = (T)(img)(_n1##x,_p2##y,z,c)), \
1486 (I[18] = (T)(img)(_n1##x,_p1##y,z,c)), \
1487 (I[25] = (T)(img)(_n1##x,y,z,c)), \
1488 (I[32] = (T)(img)(_n1##x,_n1##y,z,c)), \
1489 (I[39] = (T)(img)(_n1##x,_n2##y,z,c)), \
1490 (I[46] = (T)(img)(_n1##x,_n3##y,z,c)), \
1491 (I[5] = (T)(img)(_n2##x,_p3##y,z,c)), \
1492 (I[12] = (T)(img)(_n2##x,_p2##y,z,c)), \
1493 (I[19] = (T)(img)(_n2##x,_p1##y,z,c)), \
1494 (I[26] = (T)(img)(_n2##x,y,z,c)), \
1495 (I[33] = (T)(img)(_n2##x,_n1##y,z,c)), \
1496 (I[40] = (T)(img)(_n2##x,_n2##y,z,c)), \
1497 (I[47] = (T)(img)(_n2##x,_n3##y,z,c)), \
1498 x+3>=(int)(img)._width?(img).width()-1:x+3); \
1499 x<=(int)(x1) && ((_n3##x<(img).width() && ( \
1500 (I[6] = (T)(img)(_n3##x,_p3##y,z,c)), \
1501 (I[13] = (T)(img)(_n3##x,_p2##y,z,c)), \
1502 (I[20] = (T)(img)(_n3##x,_p1##y,z,c)), \
1503 (I[27] = (T)(img)(_n3##x,y,z,c)), \
1504 (I[34] = (T)(img)(_n3##x,_n1##y,z,c)), \
1505 (I[41] = (T)(img)(_n3##x,_n2##y,z,c)), \
1506 (I[48] = (T)(img)(_n3##x,_n3##y,z,c)),1)) || \
1507 _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n3##x = _n2##x = --_n1##x)); \
1508 I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], \
1509 I[7] = I[8], I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], \
1510 I[14] = I[15], I[15] = I[16], I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], \
1511 I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], I[26] = I[27], \
1512 I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], \
1513 I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], \
1514 I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], I[47] = I[48], \
1515 _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x)
1517 #define cimg_for8x8(img,x,y,z,c,I,T) \
1518 cimg_for8((img)._height,y) for (int x = 0, \
1519 _p3##x = 0, _p2##x = 0, _p1##x = 0, \
1520 _n1##x = 1>=((img)._width)?(img).width()-1:1, \
1521 _n2##x = 2>=((img)._width)?(img).width()-1:2, \
1522 _n3##x = 3>=((img)._width)?(img).width()-1:3, \
1524 (I[0] = I[1] = I[2] = I[3] = (T)(img)(_p3##x,_p3##y,z,c)), \
1525 (I[8] = I[9] = I[10] = I[11] = (T)(img)(0,_p2##y,z,c)), \
1526 (I[16] = I[17] = I[18] = I[19] = (T)(img)(0,_p1##y,z,c)), \
1527 (I[24] = I[25] = I[26] = I[27] = (T)(img)(0,y,z,c)), \
1528 (I[32] = I[33] = I[34] = I[35] = (T)(img)(0,_n1##y,z,c)), \
1529 (I[40] = I[41] = I[42] = I[43] = (T)(img)(0,_n2##y,z,c)), \
1530 (I[48] = I[49] = I[50] = I[51] = (T)(img)(0,_n3##y,z,c)), \
1531 (I[56] = I[57] = I[58] = I[59] = (T)(img)(0,_n4##y,z,c)), \
1532 (I[4] = (T)(img)(_n1##x,_p3##y,z,c)), \
1533 (I[12] = (T)(img)(_n1##x,_p2##y,z,c)), \
1534 (I[20] = (T)(img)(_n1##x,_p1##y,z,c)), \
1535 (I[28] = (T)(img)(_n1##x,y,z,c)), \
1536 (I[36] = (T)(img)(_n1##x,_n1##y,z,c)), \
1537 (I[44] = (T)(img)(_n1##x,_n2##y,z,c)), \
1538 (I[52] = (T)(img)(_n1##x,_n3##y,z,c)), \
1539 (I[60] = (T)(img)(_n1##x,_n4##y,z,c)), \
1540 (I[5] = (T)(img)(_n2##x,_p3##y,z,c)), \
1541 (I[13] = (T)(img)(_n2##x,_p2##y,z,c)), \
1542 (I[21] = (T)(img)(_n2##x,_p1##y,z,c)), \
1543 (I[29] = (T)(img)(_n2##x,y,z,c)), \
1544 (I[37] = (T)(img)(_n2##x,_n1##y,z,c)), \
1545 (I[45] = (T)(img)(_n2##x,_n2##y,z,c)), \
1546 (I[53] = (T)(img)(_n2##x,_n3##y,z,c)), \
1547 (I[61] = (T)(img)(_n2##x,_n4##y,z,c)), \
1548 (I[6] = (T)(img)(_n3##x,_p3##y,z,c)), \
1549 (I[14] = (T)(img)(_n3##x,_p2##y,z,c)), \
1550 (I[22] = (T)(img)(_n3##x,_p1##y,z,c)), \
1551 (I[30] = (T)(img)(_n3##x,y,z,c)), \
1552 (I[38] = (T)(img)(_n3##x,_n1##y,z,c)), \
1553 (I[46] = (T)(img)(_n3##x,_n2##y,z,c)), \
1554 (I[54] = (T)(img)(_n3##x,_n3##y,z,c)), \
1555 (I[62] = (T)(img)(_n3##x,_n4##y,z,c)), \
1556 4>=((img)._width)?(img).width()-1:4); \
1557 (_n4##x<(img).width() && ( \
1558 (I[7] = (T)(img)(_n4##x,_p3##y,z,c)), \
1559 (I[15] = (T)(img)(_n4##x,_p2##y,z,c)), \
1560 (I[23] = (T)(img)(_n4##x,_p1##y,z,c)), \
1561 (I[31] = (T)(img)(_n4##x,y,z,c)), \
1562 (I[39] = (T)(img)(_n4##x,_n1##y,z,c)), \
1563 (I[47] = (T)(img)(_n4##x,_n2##y,z,c)), \
1564 (I[55] = (T)(img)(_n4##x,_n3##y,z,c)), \
1565 (I[63] = (T)(img)(_n4##x,_n4##y,z,c)),1)) || \
1566 _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n4##x = _n3##x = _n2##x = --_n1##x); \
1567 I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], \
1568 I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], \
1569 I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], \
1570 I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], \
1571 I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], \
1572 I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], \
1573 I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], \
1574 I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], \
1575 _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x)
1577 #define cimg_for_in8x8(img,x0,y0,x1,y1,x,y,z,c,I,T) \
1578 cimg_for_in8((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \
1579 _p3##x = x-3<0?0:x-3, \
1580 _p2##x = x-2<0?0:x-2, \
1581 _p1##x = x-1<0?0:x-1, \
1582 _n1##x = x+1>=(img).width()?(img).width()-1:x+1, \
1583 _n2##x = x+2>=(img).width()?(img).width()-1:x+2, \
1584 _n3##x = x+3>=(img).width()?(img).width()-1:x+3, \
1586 (I[0] = (T)(img)(_p3##x,_p3##y,z,c)), \
1587 (I[8] = (T)(img)(_p3##x,_p2##y,z,c)), \
1588 (I[16] = (T)(img)(_p3##x,_p1##y,z,c)), \
1589 (I[24] = (T)(img)(_p3##x,y,z,c)), \
1590 (I[32] = (T)(img)(_p3##x,_n1##y,z,c)), \
1591 (I[40] = (T)(img)(_p3##x,_n2##y,z,c)), \
1592 (I[48] = (T)(img)(_p3##x,_n3##y,z,c)), \
1593 (I[56] = (T)(img)(_p3##x,_n4##y,z,c)), \
1594 (I[1] = (T)(img)(_p2##x,_p3##y,z,c)), \
1595 (I[9] = (T)(img)(_p2##x,_p2##y,z,c)), \
1596 (I[17] = (T)(img)(_p2##x,_p1##y,z,c)), \
1597 (I[25] = (T)(img)(_p2##x,y,z,c)), \
1598 (I[33] = (T)(img)(_p2##x,_n1##y,z,c)), \
1599 (I[41] = (T)(img)(_p2##x,_n2##y,z,c)), \
1600 (I[49] = (T)(img)(_p2##x,_n3##y,z,c)), \
1601 (I[57] = (T)(img)(_p2##x,_n4##y,z,c)), \
1602 (I[2] = (T)(img)(_p1##x,_p3##y,z,c)), \
1603 (I[10] = (T)(img)(_p1##x,_p2##y,z,c)), \
1604 (I[18] = (T)(img)(_p1##x,_p1##y,z,c)), \
1605 (I[26] = (T)(img)(_p1##x,y,z,c)), \
1606 (I[34] = (T)(img)(_p1##x,_n1##y,z,c)), \
1607 (I[42] = (T)(img)(_p1##x,_n2##y,z,c)), \
1608 (I[50] = (T)(img)(_p1##x,_n3##y,z,c)), \
1609 (I[58] = (T)(img)(_p1##x,_n4##y,z,c)), \
1610 (I[3] = (T)(img)(x,_p3##y,z,c)), \
1611 (I[11] = (T)(img)(x,_p2##y,z,c)), \
1612 (I[19] = (T)(img)(x,_p1##y,z,c)), \
1613 (I[27] = (T)(img)(x,y,z,c)), \
1614 (I[35] = (T)(img)(x,_n1##y,z,c)), \
1615 (I[43] = (T)(img)(x,_n2##y,z,c)), \
1616 (I[51] = (T)(img)(x,_n3##y,z,c)), \
1617 (I[59] = (T)(img)(x,_n4##y,z,c)), \
1618 (I[4] = (T)(img)(_n1##x,_p3##y,z,c)), \
1619 (I[12] = (T)(img)(_n1##x,_p2##y,z,c)), \
1620 (I[20] = (T)(img)(_n1##x,_p1##y,z,c)), \
1621 (I[28] = (T)(img)(_n1##x,y,z,c)), \
1622 (I[36] = (T)(img)(_n1##x,_n1##y,z,c)), \
1623 (I[44] = (T)(img)(_n1##x,_n2##y,z,c)), \
1624 (I[52] = (T)(img)(_n1##x,_n3##y,z,c)), \
1625 (I[60] = (T)(img)(_n1##x,_n4##y,z,c)), \
1626 (I[5] = (T)(img)(_n2##x,_p3##y,z,c)), \
1627 (I[13] = (T)(img)(_n2##x,_p2##y,z,c)), \
1628 (I[21] = (T)(img)(_n2##x,_p1##y,z,c)), \
1629 (I[29] = (T)(img)(_n2##x,y,z,c)), \
1630 (I[37] = (T)(img)(_n2##x,_n1##y,z,c)), \
1631 (I[45] = (T)(img)(_n2##x,_n2##y,z,c)), \
1632 (I[53] = (T)(img)(_n2##x,_n3##y,z,c)), \
1633 (I[61] = (T)(img)(_n2##x,_n4##y,z,c)), \
1634 (I[6] = (T)(img)(_n3##x,_p3##y,z,c)), \
1635 (I[14] = (T)(img)(_n3##x,_p2##y,z,c)), \
1636 (I[22] = (T)(img)(_n3##x,_p1##y,z,c)), \
1637 (I[30] = (T)(img)(_n3##x,y,z,c)), \
1638 (I[38] = (T)(img)(_n3##x,_n1##y,z,c)), \
1639 (I[46] = (T)(img)(_n3##x,_n2##y,z,c)), \
1640 (I[54] = (T)(img)(_n3##x,_n3##y,z,c)), \
1641 (I[62] = (T)(img)(_n3##x,_n4##y,z,c)), \
1642 x+4>=(img).width()?(img).width()-1:x+4); \
1643 x<=(int)(x1) && ((_n4##x<(img).width() && ( \
1644 (I[7] = (T)(img)(_n4##x,_p3##y,z,c)), \
1645 (I[15] = (T)(img)(_n4##x,_p2##y,z,c)), \
1646 (I[23] = (T)(img)(_n4##x,_p1##y,z,c)), \
1647 (I[31] = (T)(img)(_n4##x,y,z,c)), \
1648 (I[39] = (T)(img)(_n4##x,_n1##y,z,c)), \
1649 (I[47] = (T)(img)(_n4##x,_n2##y,z,c)), \
1650 (I[55] = (T)(img)(_n4##x,_n3##y,z,c)), \
1651 (I[63] = (T)(img)(_n4##x,_n4##y,z,c)),1)) || \
1652 _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n4##x = _n3##x = _n2##x = --_n1##x)); \
1653 I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], \
1654 I[8] = I[9], I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], \
1655 I[16] = I[17], I[17] = I[18], I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], \
1656 I[24] = I[25], I[25] = I[26], I[26] = I[27], I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], \
1657 I[32] = I[33], I[33] = I[34], I[34] = I[35], I[35] = I[36], I[36] = I[37], I[37] = I[38], I[38] = I[39], \
1658 I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], I[44] = I[45], I[45] = I[46], I[46] = I[47], \
1659 I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], I[53] = I[54], I[54] = I[55], \
1660 I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], I[62] = I[63], \
1661 _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x)
1663 #define cimg_for9x9(img,x,y,z,c,I,T) \
1664 cimg_for9((img)._height,y) for (int x = 0, \
1665 _p4##x = 0, _p3##x = 0, _p2##x = 0, _p1##x = 0, \
1666 _n1##x = 1>=((img)._width)?(img).width()-1:1, \
1667 _n2##x = 2>=((img)._width)?(img).width()-1:2, \
1668 _n3##x = 3>=((img)._width)?(img).width()-1:3, \
1670 (I[0] = I[1] = I[2] = I[3] = I[4] = (T)(img)(_p4##x,_p4##y,z,c)), \
1671 (I[9] = I[10] = I[11] = I[12] = I[13] = (T)(img)(0,_p3##y,z,c)), \
1672 (I[18] = I[19] = I[20] = I[21] = I[22] = (T)(img)(0,_p2##y,z,c)), \
1673 (I[27] = I[28] = I[29] = I[30] = I[31] = (T)(img)(0,_p1##y,z,c)), \
1674 (I[36] = I[37] = I[38] = I[39] = I[40] = (T)(img)(0,y,z,c)), \
1675 (I[45] = I[46] = I[47] = I[48] = I[49] = (T)(img)(0,_n1##y,z,c)), \
1676 (I[54] = I[55] = I[56] = I[57] = I[58] = (T)(img)(0,_n2##y,z,c)), \
1677 (I[63] = I[64] = I[65] = I[66] = I[67] = (T)(img)(0,_n3##y,z,c)), \
1678 (I[72] = I[73] = I[74] = I[75] = I[76] = (T)(img)(0,_n4##y,z,c)), \
1679 (I[5] = (T)(img)(_n1##x,_p4##y,z,c)), \
1680 (I[14] = (T)(img)(_n1##x,_p3##y,z,c)), \
1681 (I[23] = (T)(img)(_n1##x,_p2##y,z,c)), \
1682 (I[32] = (T)(img)(_n1##x,_p1##y,z,c)), \
1683 (I[41] = (T)(img)(_n1##x,y,z,c)), \
1684 (I[50] = (T)(img)(_n1##x,_n1##y,z,c)), \
1685 (I[59] = (T)(img)(_n1##x,_n2##y,z,c)), \
1686 (I[68] = (T)(img)(_n1##x,_n3##y,z,c)), \
1687 (I[77] = (T)(img)(_n1##x,_n4##y,z,c)), \
1688 (I[6] = (T)(img)(_n2##x,_p4##y,z,c)), \
1689 (I[15] = (T)(img)(_n2##x,_p3##y,z,c)), \
1690 (I[24] = (T)(img)(_n2##x,_p2##y,z,c)), \
1691 (I[33] = (T)(img)(_n2##x,_p1##y,z,c)), \
1692 (I[42] = (T)(img)(_n2##x,y,z,c)), \
1693 (I[51] = (T)(img)(_n2##x,_n1##y,z,c)), \
1694 (I[60] = (T)(img)(_n2##x,_n2##y,z,c)), \
1695 (I[69] = (T)(img)(_n2##x,_n3##y,z,c)), \
1696 (I[78] = (T)(img)(_n2##x,_n4##y,z,c)), \
1697 (I[7] = (T)(img)(_n3##x,_p4##y,z,c)), \
1698 (I[16] = (T)(img)(_n3##x,_p3##y,z,c)), \
1699 (I[25] = (T)(img)(_n3##x,_p2##y,z,c)), \
1700 (I[34] = (T)(img)(_n3##x,_p1##y,z,c)), \
1701 (I[43] = (T)(img)(_n3##x,y,z,c)), \
1702 (I[52] = (T)(img)(_n3##x,_n1##y,z,c)), \
1703 (I[61] = (T)(img)(_n3##x,_n2##y,z,c)), \
1704 (I[70] = (T)(img)(_n3##x,_n3##y,z,c)), \
1705 (I[79] = (T)(img)(_n3##x,_n4##y,z,c)), \
1706 4>=((img)._width)?(img).width()-1:4); \
1707 (_n4##x<(img).width() && ( \
1708 (I[8] = (T)(img)(_n4##x,_p4##y,z,c)), \
1709 (I[17] = (T)(img)(_n4##x,_p3##y,z,c)), \
1710 (I[26] = (T)(img)(_n4##x,_p2##y,z,c)), \
1711 (I[35] = (T)(img)(_n4##x,_p1##y,z,c)), \
1712 (I[44] = (T)(img)(_n4##x,y,z,c)), \
1713 (I[53] = (T)(img)(_n4##x,_n1##y,z,c)), \
1714 (I[62] = (T)(img)(_n4##x,_n2##y,z,c)), \
1715 (I[71] = (T)(img)(_n4##x,_n3##y,z,c)), \
1716 (I[80] = (T)(img)(_n4##x,_n4##y,z,c)),1)) || \
1717 _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n4##x = _n3##x = _n2##x = --_n1##x); \
1718 I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], \
1719 I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], \
1720 I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], \
1721 I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], \
1722 I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], \
1723 I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], \
1724 I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], \
1725 I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], \
1726 I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], \
1727 _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x)
1729 #define cimg_for_in9x9(img,x0,y0,x1,y1,x,y,z,c,I,T) \
1730 cimg_for_in9((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \
1731 _p4##x = x-4<0?0:x-4, \
1732 _p3##x = x-3<0?0:x-3, \
1733 _p2##x = x-2<0?0:x-2, \
1734 _p1##x = x-1<0?0:x-1, \
1735 _n1##x = x+1>=(img).width()?(img).width()-1:x+1, \
1736 _n2##x = x+2>=(img).width()?(img).width()-1:x+2, \
1737 _n3##x = x+3>=(img).width()?(img).width()-1:x+3, \
1739 (I[0] = (T)(img)(_p4##x,_p4##y,z,c)), \
1740 (I[9] = (T)(img)(_p4##x,_p3##y,z,c)), \
1741 (I[18] = (T)(img)(_p4##x,_p2##y,z,c)), \
1742 (I[27] = (T)(img)(_p4##x,_p1##y,z,c)), \
1743 (I[36] = (T)(img)(_p4##x,y,z,c)), \
1744 (I[45] = (T)(img)(_p4##x,_n1##y,z,c)), \
1745 (I[54] = (T)(img)(_p4##x,_n2##y,z,c)), \
1746 (I[63] = (T)(img)(_p4##x,_n3##y,z,c)), \
1747 (I[72] = (T)(img)(_p4##x,_n4##y,z,c)), \
1748 (I[1] = (T)(img)(_p3##x,_p4##y,z,c)), \
1749 (I[10] = (T)(img)(_p3##x,_p3##y,z,c)), \
1750 (I[19] = (T)(img)(_p3##x,_p2##y,z,c)), \
1751 (I[28] = (T)(img)(_p3##x,_p1##y,z,c)), \
1752 (I[37] = (T)(img)(_p3##x,y,z,c)), \
1753 (I[46] = (T)(img)(_p3##x,_n1##y,z,c)), \
1754 (I[55] = (T)(img)(_p3##x,_n2##y,z,c)), \
1755 (I[64] = (T)(img)(_p3##x,_n3##y,z,c)), \
1756 (I[73] = (T)(img)(_p3##x,_n4##y,z,c)), \
1757 (I[2] = (T)(img)(_p2##x,_p4##y,z,c)), \
1758 (I[11] = (T)(img)(_p2##x,_p3##y,z,c)), \
1759 (I[20] = (T)(img)(_p2##x,_p2##y,z,c)), \
1760 (I[29] = (T)(img)(_p2##x,_p1##y,z,c)), \
1761 (I[38] = (T)(img)(_p2##x,y,z,c)), \
1762 (I[47] = (T)(img)(_p2##x,_n1##y,z,c)), \
1763 (I[56] = (T)(img)(_p2##x,_n2##y,z,c)), \
1764 (I[65] = (T)(img)(_p2##x,_n3##y,z,c)), \
1765 (I[74] = (T)(img)(_p2##x,_n4##y,z,c)), \
1766 (I[3] = (T)(img)(_p1##x,_p4##y,z,c)), \
1767 (I[12] = (T)(img)(_p1##x,_p3##y,z,c)), \
1768 (I[21] = (T)(img)(_p1##x,_p2##y,z,c)), \
1769 (I[30] = (T)(img)(_p1##x,_p1##y,z,c)), \
1770 (I[39] = (T)(img)(_p1##x,y,z,c)), \
1771 (I[48] = (T)(img)(_p1##x,_n1##y,z,c)), \
1772 (I[57] = (T)(img)(_p1##x,_n2##y,z,c)), \
1773 (I[66] = (T)(img)(_p1##x,_n3##y,z,c)), \
1774 (I[75] = (T)(img)(_p1##x,_n4##y,z,c)), \
1775 (I[4] = (T)(img)(x,_p4##y,z,c)), \
1776 (I[13] = (T)(img)(x,_p3##y,z,c)), \
1777 (I[22] = (T)(img)(x,_p2##y,z,c)), \
1778 (I[31] = (T)(img)(x,_p1##y,z,c)), \
1779 (I[40] = (T)(img)(x,y,z,c)), \
1780 (I[49] = (T)(img)(x,_n1##y,z,c)), \
1781 (I[58] = (T)(img)(x,_n2##y,z,c)), \
1782 (I[67] = (T)(img)(x,_n3##y,z,c)), \
1783 (I[76] = (T)(img)(x,_n4##y,z,c)), \
1784 (I[5] = (T)(img)(_n1##x,_p4##y,z,c)), \
1785 (I[14] = (T)(img)(_n1##x,_p3##y,z,c)), \
1786 (I[23] = (T)(img)(_n1##x,_p2##y,z,c)), \
1787 (I[32] = (T)(img)(_n1##x,_p1##y,z,c)), \
1788 (I[41] = (T)(img)(_n1##x,y,z,c)), \
1789 (I[50] = (T)(img)(_n1##x,_n1##y,z,c)), \
1790 (I[59] = (T)(img)(_n1##x,_n2##y,z,c)), \
1791 (I[68] = (T)(img)(_n1##x,_n3##y,z,c)), \
1792 (I[77] = (T)(img)(_n1##x,_n4##y,z,c)), \
1793 (I[6] = (T)(img)(_n2##x,_p4##y,z,c)), \
1794 (I[15] = (T)(img)(_n2##x,_p3##y,z,c)), \
1795 (I[24] = (T)(img)(_n2##x,_p2##y,z,c)), \
1796 (I[33] = (T)(img)(_n2##x,_p1##y,z,c)), \
1797 (I[42] = (T)(img)(_n2##x,y,z,c)), \
1798 (I[51] = (T)(img)(_n2##x,_n1##y,z,c)), \
1799 (I[60] = (T)(img)(_n2##x,_n2##y,z,c)), \
1800 (I[69] = (T)(img)(_n2##x,_n3##y,z,c)), \
1801 (I[78] = (T)(img)(_n2##x,_n4##y,z,c)), \
1802 (I[7] = (T)(img)(_n3##x,_p4##y,z,c)), \
1803 (I[16] = (T)(img)(_n3##x,_p3##y,z,c)), \
1804 (I[25] = (T)(img)(_n3##x,_p2##y,z,c)), \
1805 (I[34] = (T)(img)(_n3##x,_p1##y,z,c)), \
1806 (I[43] = (T)(img)(_n3##x,y,z,c)), \
1807 (I[52] = (T)(img)(_n3##x,_n1##y,z,c)), \
1808 (I[61] = (T)(img)(_n3##x,_n2##y,z,c)), \
1809 (I[70] = (T)(img)(_n3##x,_n3##y,z,c)), \
1810 (I[79] = (T)(img)(_n3##x,_n4##y,z,c)), \
1811 x+4>=(img).width()?(img).width()-1:x+4); \
1812 x<=(int)(x1) && ((_n4##x<(img).width() && ( \
1813 (I[8] = (T)(img)(_n4##x,_p4##y,z,c)), \
1814 (I[17] = (T)(img)(_n4##x,_p3##y,z,c)), \
1815 (I[26] = (T)(img)(_n4##x,_p2##y,z,c)), \
1816 (I[35] = (T)(img)(_n4##x,_p1##y,z,c)), \
1817 (I[44] = (T)(img)(_n4##x,y,z,c)), \
1818 (I[53] = (T)(img)(_n4##x,_n1##y,z,c)), \
1819 (I[62] = (T)(img)(_n4##x,_n2##y,z,c)), \
1820 (I[71] = (T)(img)(_n4##x,_n3##y,z,c)), \
1821 (I[80] = (T)(img)(_n4##x,_n4##y,z,c)),1)) || \
1822 _n3##x==--_n4##x || _n2##x==--_n3##x || _n1##x==--_n2##x || x==(_n4##x = _n3##x = _n2##x = --_n1##x)); \
1823 I[0] = I[1], I[1] = I[2], I[2] = I[3], I[3] = I[4], I[4] = I[5], I[5] = I[6], I[6] = I[7], I[7] = I[8], \
1824 I[9] = I[10], I[10] = I[11], I[11] = I[12], I[12] = I[13], I[13] = I[14], I[14] = I[15], I[15] = I[16], I[16] = I[17], \
1825 I[18] = I[19], I[19] = I[20], I[20] = I[21], I[21] = I[22], I[22] = I[23], I[23] = I[24], I[24] = I[25], I[25] = I[26], \
1826 I[27] = I[28], I[28] = I[29], I[29] = I[30], I[30] = I[31], I[31] = I[32], I[32] = I[33], I[33] = I[34], I[34] = I[35], \
1827 I[36] = I[37], I[37] = I[38], I[38] = I[39], I[39] = I[40], I[40] = I[41], I[41] = I[42], I[42] = I[43], I[43] = I[44], \
1828 I[45] = I[46], I[46] = I[47], I[47] = I[48], I[48] = I[49], I[49] = I[50], I[50] = I[51], I[51] = I[52], I[52] = I[53], \
1829 I[54] = I[55], I[55] = I[56], I[56] = I[57], I[57] = I[58], I[58] = I[59], I[59] = I[60], I[60] = I[61], I[61] = I[62], \
1830 I[63] = I[64], I[64] = I[65], I[65] = I[66], I[66] = I[67], I[67] = I[68], I[68] = I[69], I[69] = I[70], I[70] = I[71], \
1831 I[72] = I[73], I[73] = I[74], I[74] = I[75], I[75] = I[76], I[76] = I[77], I[77] = I[78], I[78] = I[79], I[79] = I[80], \
1832 _p4##x = _p3##x, _p3##x = _p2##x, _p2##x = _p1##x, _p1##x = x++, ++_n1##x, ++_n2##x, ++_n3##x, ++_n4##x)
1834 #define cimg_for2x2x2(img,x,y,z,c,I,T) \
1835 cimg_for2((img)._depth,z) cimg_for2((img)._height,y) for (int x = 0, \
1837 (I[0] = (T)(img)(0,y,z,c)), \
1838 (I[2] = (T)(img)(0,_n1##y,z,c)), \
1839 (I[4] = (T)(img)(0,y,_n1##z,c)), \
1840 (I[6] = (T)(img)(0,_n1##y,_n1##z,c)), \
1841 1>=(img)._width?(img).width()-1:1); \
1842 (_n1##x<(img).width() && ( \
1843 (I[1] = (T)(img)(_n1##x,y,z,c)), \
1844 (I[3] = (T)(img)(_n1##x,_n1##y,z,c)), \
1845 (I[5] = (T)(img)(_n1##x,y,_n1##z,c)), \
1846 (I[7] = (T)(img)(_n1##x,_n1##y,_n1##z,c)),1)) || \
1848 I[0] = I[1], I[2] = I[3], I[4] = I[5], I[6] = I[7], \
1851 #define cimg_for_in2x2x2(img,x0,y0,z0,x1,y1,z1,x,y,z,c,I,T) \
1852 cimg_for_in2((img)._depth,z0,z1,z) cimg_for_in2((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \
1854 (I[0] = (T)(img)(x,y,z,c)), \
1855 (I[2] = (T)(img)(x,_n1##y,z,c)), \
1856 (I[4] = (T)(img)(x,y,_n1##z,c)), \
1857 (I[6] = (T)(img)(x,_n1##y,_n1##z,c)), \
1858 x+1>=(int)(img)._width?(img).width()-1:x+1); \
1859 x<=(int)(x1) && ((_n1##x<(img).width() && ( \
1860 (I[1] = (T)(img)(_n1##x,y,z,c)), \
1861 (I[3] = (T)(img)(_n1##x,_n1##y,z,c)), \
1862 (I[5] = (T)(img)(_n1##x,y,_n1##z,c)), \
1863 (I[7] = (T)(img)(_n1##x,_n1##y,_n1##z,c)),1)) || \
1865 I[0] = I[1], I[2] = I[3], I[4] = I[5], I[6] = I[7], \
1868 #define cimg_for3x3x3(img,x,y,z,c,I,T) \
1869 cimg_for3((img)._depth,z) cimg_for3((img)._height,y) for (int x = 0, \
1872 (I[0] = I[1] = (T)(img)(_p1##x,_p1##y,_p1##z,c)), \
1873 (I[3] = I[4] = (T)(img)(0,y,_p1##z,c)), \
1874 (I[6] = I[7] = (T)(img)(0,_n1##y,_p1##z,c)), \
1875 (I[9] = I[10] = (T)(img)(0,_p1##y,z,c)), \
1876 (I[12] = I[13] = (T)(img)(0,y,z,c)), \
1877 (I[15] = I[16] = (T)(img)(0,_n1##y,z,c)), \
1878 (I[18] = I[19] = (T)(img)(0,_p1##y,_n1##z,c)), \
1879 (I[21] = I[22] = (T)(img)(0,y,_n1##z,c)), \
1880 (I[24] = I[25] = (T)(img)(0,_n1##y,_n1##z,c)), \
1881 1>=(img)._width?(img).width()-1:1); \
1882 (_n1##x<(img).width() && ( \
1883 (I[2] = (T)(img)(_n1##x,_p1##y,_p1##z,c)), \
1884 (I[5] = (T)(img)(_n1##x,y,_p1##z,c)), \
1885 (I[8] = (T)(img)(_n1##x,_n1##y,_p1##z,c)), \
1886 (I[11] = (T)(img)(_n1##x,_p1##y,z,c)), \
1887 (I[14] = (T)(img)(_n1##x,y,z,c)), \
1888 (I[17] = (T)(img)(_n1##x,_n1##y,z,c)), \
1889 (I[20] = (T)(img)(_n1##x,_p1##y,_n1##z,c)), \
1890 (I[23] = (T)(img)(_n1##x,y,_n1##z,c)), \
1891 (I[26] = (T)(img)(_n1##x,_n1##y,_n1##z,c)),1)) || \
1893 I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], \
1894 I[9] = I[10], I[10] = I[11], I[12] = I[13], I[13] = I[14], I[15] = I[16], I[16] = I[17], \
1895 I[18] = I[19], I[19] = I[20], I[21] = I[22], I[22] = I[23], I[24] = I[25], I[25] = I[26], \
1896 _p1##x = x++, ++_n1##x)
1898 #define cimg_for_in3x3x3(img,x0,y0,z0,x1,y1,z1,x,y,z,c,I,T) \
1899 cimg_for_in3((img)._depth,z0,z1,z) cimg_for_in3((img)._height,y0,y1,y) for (int x = (int)(x0)<0?0:(int)(x0), \
1900 _p1##x = x-1<0?0:x-1, \
1902 (I[0] = (T)(img)(_p1##x,_p1##y,_p1##z,c)), \
1903 (I[3] = (T)(img)(_p1##x,y,_p1##z,c)), \
1904 (I[6] = (T)(img)(_p1##x,_n1##y,_p1##z,c)), \
1905 (I[9] = (T)(img)(_p1##x,_p1##y,z,c)), \
1906 (I[12] = (T)(img)(_p1##x,y,z,c)), \
1907 (I[15] = (T)(img)(_p1##x,_n1##y,z,c)), \
1908 (I[18] = (T)(img)(_p1##x,_p1##y,_n1##z,c)), \
1909 (I[21] = (T)(img)(_p1##x,y,_n1##z,c)), \
1910 (I[24] = (T)(img)(_p1##x,_n1##y,_n1##z,c)), \
1911 (I[1] = (T)(img)(x,_p1##y,_p1##z,c)), \
1912 (I[4] = (T)(img)(x,y,_p1##z,c)), \
1913 (I[7] = (T)(img)(x,_n1##y,_p1##z,c)), \
1914 (I[10] = (T)(img)(x,_p1##y,z,c)), \
1915 (I[13] = (T)(img)(x,y,z,c)), \
1916 (I[16] = (T)(img)(x,_n1##y,z,c)), \
1917 (I[19] = (T)(img)(x,_p1##y,_n1##z,c)), \
1918 (I[22] = (T)(img)(x,y,_n1##z,c)), \
1919 (I[25] = (T)(img)(x,_n1##y,_n1##z,c)), \
1920 x+1>=(int)(img)._width?(img).width()-1:x+1); \
1921 x<=(int)(x1) && ((_n1##x<(img).width() && ( \
1922 (I[2] = (T)(img)(_n1##x,_p1##y,_p1##z,c)), \
1923 (I[5] = (T)(img)(_n1##x,y,_p1##z,c)), \
1924 (I[8] = (T)(img)(_n1##x,_n1##y,_p1##z,c)), \
1925 (I[11] = (T)(img)(_n1##x,_p1##y,z,c)), \
1926 (I[14] = (T)(img)(_n1##x,y,z,c)), \
1927 (I[17] = (T)(img)(_n1##x,_n1##y,z,c)), \
1928 (I[20] = (T)(img)(_n1##x,_p1##y,_n1##z,c)), \
1929 (I[23] = (T)(img)(_n1##x,y,_n1##z,c)), \
1930 (I[26] = (T)(img)(_n1##x,_n1##y,_n1##z,c)),1)) || \
1932 I[0] = I[1], I[1] = I[2], I[3] = I[4], I[4] = I[5], I[6] = I[7], I[7] = I[8], \
1933 I[9] = I[10], I[10] = I[11], I[12] = I[13], I[13] = I[14], I[15] = I[16], I[16] = I[17], \
1934 I[18] = I[19], I[19] = I[20], I[21] = I[22], I[22] = I[23], I[24] = I[25], I[25] = I[26], \
1935 _p1##x = x++, ++_n1##x)
1937 #define cimglist_for(list,l) for (int l = 0; l<(int)(list)._width; ++l)
1938 #define cimglist_for_in(list,l0,l1,l) \
1939 for (int l = (int)(l0)<0?0:(int)(l0), _max##l = (unsigned int)l1<(list)._width?(int)(l1):(int)(list)._width-1; l<=_max##l; ++l)
1941 #define cimglist_apply(list,fn) cimglist_for(list,__##fn) (list)[__##fn].fn
1945 #define _cimgdisplay_instance "[instance(%u,%u,%u,%c%s%c)] CImgDisplay::"
1946 #define cimgdisplay_instance _width,_height,_normalization,_title?'\"':'[',_title?_title:"untitled",_title?'\"':']'
1947 #define _cimg_instance "[instance(%u,%u,%u,%u,%p,%sshared)] CImg<%s>::"
1948 #define cimg_instance _width,_height,_depth,_spectrum,_data,_is_shared?"":"non-",pixel_type()
1949 #define _cimglist_instance "[instance(%u,%u,%p)] CImgList<%s>::"
1950 #define cimglist_instance _width,_allocated_width,_data,pixel_type()
1971 namespace cimg_library_suffixed {
1974 template<
typename T=
float>
struct CImg;
1986 #ifdef cimg_use_vt100
1987 const char t_normal[] = { 0x1b,
'[',
'0',
';',
'0',
';',
'0',
'm', 0 };
1988 const char t_black[] = { 0x1b,
'[',
'0',
';',
'3',
'0',
';',
'5',
'9',
'm', 0 };
1989 const char t_red[] = { 0x1b,
'[',
'0',
';',
'3',
'1',
';',
'5',
'9',
'm', 0 };
1990 const char t_green[] = { 0x1b,
'[',
'0',
';',
'3',
'2',
';',
'5',
'9',
'm', 0 };
1991 const char t_yellow[] = { 0x1b,
'[',
'0',
';',
'3',
'3',
';',
'5',
'9',
'm', 0 };
1992 const char t_blue[] = { 0x1b,
'[',
'0',
';',
'3',
'4',
';',
'5',
'9',
'm', 0 };
1993 const char t_magenta[] = { 0x1b,
'[',
'0',
';',
'3',
'5',
';',
'5',
'9',
'm', 0 };
1994 const char t_cyan[] = { 0x1b,
'[',
'0',
';',
'3',
'6',
';',
'5',
'9',
'm', 0 };
1995 const char t_white[] = { 0x1b,
'[',
'0',
';',
'3',
'7',
';',
'5',
'9',
'm', 0 };
1996 const char t_bold[] = { 0x1b,
'[',
'1',
'm', 0 };
1997 const char t_underscore[] = { 0x1b,
'[',
'4',
'm', 0 };
1999 const char t_normal[] = { 0 };
2000 const char *
const t_black = cimg::t_normal,
2001 *
const t_red = cimg::t_normal,
2002 *
const t_green = cimg::t_normal,
2003 *
const t_yellow = cimg::t_normal,
2004 *
const t_blue = cimg::t_normal,
2005 *
const t_magenta = cimg::t_normal,
2006 *
const t_cyan = cimg::t_normal,
2007 *
const t_white = cimg::t_normal,
2008 *
const t_bold = cimg::t_normal,
2009 *
const t_underscore = cimg::t_normal;
2012 inline std::FILE*
output(std::FILE *file=0);
2016 template<
typename T>
2019 inline unsigned int& _exception_mode(
const unsigned int value,
const bool is_set) {
2020 static unsigned int mode = cimg_verbosity;
2021 if (is_set) mode = value;
2036 return _exception_mode(mode,
true);
2044 return _exception_mode(0,
false);
2047 inline int dialog(
const char *
const title,
const char *
const msg,
const char *
const button1_label=
"OK",
2048 const char *
const button2_label=0,
const char *
const button3_label=0,
2049 const char *
const button4_label=0,
const char *
const button5_label=0,
2050 const char *
const button6_label=0,
const bool centering=
false);
2052 inline double eval(
const char *
const expression,
const double x=0,
const double y=0,
const double z=0,
const double c=0);
2120 #define _cimg_exception_err(etype,disp_flag) \
2121 std::va_list ap; va_start(ap,format); cimg_vsnprintf(_message,sizeof(_message),format,ap); va_end(ap); \
2122 if (cimg::exception_mode()) { \
2123 std::fprintf(cimg::output(),"\n%s[CImg] *** %s ***%s %s\n",cimg::t_red,etype,cimg::t_normal,_message); \
2124 if (cimg_display && disp_flag && !(cimg::exception_mode()%2)) try { cimg::dialog(etype,_message,"Abort"); } catch (CImgException&) {} \
2125 if (cimg::exception_mode()>=3) cimg_library_suffixed::cimg::info(); \
2128 char _message[16384];
2130 CImgException(
const char *
const format, ...) { _cimg_exception_err(
"CImgException",
true); }
2132 const char *
what()
const throw() {
return _message; }
2138 CImgInstanceException(
const char *
const format, ...) { _cimg_exception_err(
"CImgInstanceException",
true); }
2144 CImgArgumentException(
const char *
const format, ...) { _cimg_exception_err(
"CImgArgumentException",
true); }
2150 CImgIOException(
const char *
const format, ...) { _cimg_exception_err(
"CImgIOException",
true); }
2156 CImgDisplayException(
const char *
const format, ...) { _cimg_exception_err(
"CImgDisplayException",
false); }
2162 CImgWarningException(
const char *
const format, ...) { _cimg_exception_err(
"CImgWarningException",
false); }
2182 static const char* string() {
2183 static const char* s[] = {
"unknown",
"unknown8",
"unknown16",
"unknown24",
2184 "unknown32",
"unknown40",
"unknown48",
"unknown56",
2185 "unknown64",
"unknown72",
"unknown80",
"unknown88",
2186 "unknown96",
"unknown104",
"unknown112",
"unknown120",
2188 return s[(
sizeof(T)<17)?
sizeof(T):0];
2190 static bool is_float() {
return false; }
2191 static bool is_inf(
const T) {
return false; }
2192 static bool is_nan(
const T) {
return false; }
2193 static T min() {
return (T)-1>0?(T)0:(T)-1<<(8*
sizeof(T)-1); }
2194 static T max() {
return (T)-1>0?(T)-1:~((T)-1<<(8*
sizeof(T)-1)); }
2195 static T inf() {
return max(); }
2196 static T cut(
const double val) {
return val<(double)min()?min():val>(double)max()?max():(T)val; }
2197 static const char* format() {
return "%s"; }
2198 static const char* format(
const T val) {
static const char *
const s =
"unknown";
cimg::unused(val);
return s; }
2202 static const char* string() {
static const char *
const s =
"bool";
return s; }
2203 static bool is_float() {
return false; }
2204 static bool is_inf(
const bool) {
return false; }
2205 static bool is_nan(
const bool) {
return false; }
2206 static bool min() {
return false; }
2207 static bool max() {
return true; }
2208 static bool inf() {
return max(); }
2209 static bool is_inf() {
return false; }
2210 static bool cut(
const double val) {
return val<(double)min()?min():val>(double)max()?max():(
bool)val; }
2211 static const char* format() {
return "%s"; }
2212 static const char* format(
const bool val) {
static const char* s[] = {
"false",
"true" };
return s[val?1:0]; }
2215 template<>
struct type<unsigned char> {
2216 static const char* string() {
static const char *
const s =
"unsigned char";
return s; }
2217 static bool is_float() {
return false; }
2218 static bool is_inf(
const unsigned char) {
return false; }
2219 static bool is_nan(
const unsigned char) {
return false; }
2220 static unsigned char min() {
return 0; }
2221 static unsigned char max() {
return (
unsigned char)~0U; }
2222 static unsigned char inf() {
return max(); }
2223 static unsigned char cut(
const double val) {
return val<(double)min()?min():val>(double)max()?max():(
unsigned char)val; }
2224 static const char* format() {
return "%u"; }
2225 static unsigned int format(
const unsigned char val) {
return (
unsigned int)val; }
2229 static const char* string() {
static const char *
const s =
"char";
return s; }
2230 static bool is_float() {
return false; }
2231 static bool is_inf(
const char) {
return false; }
2232 static bool is_nan(
const char) {
return false; }
2233 static char min() {
return (
char)(-1L<<(8*
sizeof(char)-1)); }
2234 static char max() {
return (
char)~((char)(-1L<<(8*
sizeof(
char)-1))); }
2235 static char inf() {
return max(); }
2236 static char cut(
const double val) {
return val<(double)min()?min():val>(double)max()?max():(char)val; }
2237 static const char* format() {
return "%d"; }
2238 static int format(
const char val) {
return (
int)val; }
2241 template<>
struct type<signed char> {
2242 static const char* string() {
static const char *
const s =
"signed char";
return s; }
2243 static bool is_float() {
return false; }
2244 static bool is_inf(
const signed char) {
return false; }
2245 static bool is_nan(
const signed char) {
return false; }
2246 static signed char min() {
return (
signed char)(-1L<<(8*
sizeof(
signed char)-1)); }
2247 static signed char max() {
return ~((
signed char)(-1L<<(8*
sizeof(
signed char)-1))); }
2248 static signed char inf() {
return max(); }
2249 static signed char cut(
const double val) {
return val<(double)min()?min():val>(double)max()?max():(
signed char)val; }
2250 static const char* format() {
return "%d"; }
2251 static unsigned int format(
const signed char val) {
return (
int)val; }
2254 template<>
struct type<unsigned short> {
2255 static const char* string() {
static const char *
const s =
"unsigned short";
return s; }
2256 static bool is_float() {
return false; }
2257 static bool is_inf(
const unsigned short) {
return false; }
2258 static bool is_nan(
const unsigned short) {
return false; }
2259 static unsigned short min() {
return 0; }
2260 static unsigned short max() {
return (
unsigned short)~0U; }
2261 static unsigned short inf() {
return max(); }
2262 static unsigned short cut(
const double val) {
return val<(double)min()?min():val>(double)max()?max():(
unsigned short)val; }
2263 static const char* format() {
return "%u"; }
2264 static unsigned int format(
const unsigned short val) {
return (
unsigned int)val; }
2268 static const char* string() {
static const char *
const s =
"short";
return s; }
2269 static bool is_float() {
return false; }
2270 static bool is_inf(
const short) {
return false; }
2271 static bool is_nan(
const short) {
return false; }
2272 static short min() {
return (
short)(-1L<<(8*
sizeof(short)-1)); }
2273 static short max() {
return ~((short)(-1L<<(8*
sizeof(
short)-1))); }
2274 static short inf() {
return max(); }
2275 static short cut(
const double val) {
return val<(double)min()?min():val>(double)max()?max():(short)val; }
2276 static const char* format() {
return "%d"; }
2277 static int format(
const short val) {
return (
int)val; }
2280 template<>
struct type<unsigned int> {
2281 static const char* string() {
static const char *
const s =
"unsigned int";
return s; }
2282 static bool is_float() {
return false; }
2283 static bool is_inf(
const unsigned int) {
return false; }
2284 static bool is_nan(
const unsigned int) {
return false; }
2285 static unsigned int min() {
return 0; }
2286 static unsigned int max() {
return (
unsigned int)~0U; }
2287 static unsigned int inf() {
return max(); }
2288 static unsigned int cut(
const double val) {
return val<(double)min()?min():val>(double)max()?max():(
unsigned int)val; }
2289 static const char* format() {
return "%u"; }
2290 static unsigned int format(
const unsigned int val) {
return val; }
2294 static const char* string() {
static const char *
const s =
"int";
return s; }
2295 static bool is_float() {
return false; }
2296 static bool is_inf(
const int) {
return false; }
2297 static bool is_nan(
const int) {
return false; }
2298 static int min() {
return (
int)(-1L<<(8*
sizeof(int)-1)); }
2299 static int max() {
return ~((int)(-1L<<(8*
sizeof(
int)-1))); }
2300 static int inf() {
return max(); }
2301 static int cut(
const double val) {
return val<(double)min()?min():val>(double)max()?max():(int)val; }
2302 static const char* format() {
return "%d"; }
2303 static int format(
const int val) {
return val; }
2306 template<>
struct type<unsigned long> {
2307 static const char* string() {
static const char *
const s =
"unsigned long";
return s; }
2308 static bool is_float() {
return false; }
2309 static bool is_inf(
const unsigned long) {
return false; }
2310 static bool is_nan(
const unsigned long) {
return false; }
2311 static unsigned long min() {
return 0; }
2312 static unsigned long max() {
return (
unsigned long)~0UL; }
2313 static unsigned long inf() {
return max(); }
2314 static unsigned long cut(
const double val) {
return val<(double)min()?min():val>(double)max()?max():(
unsigned long)val; }
2315 static const char* format() {
return "%lu"; }
2316 static unsigned long format(
const unsigned long val) {
return val; }
2320 static const char* string() {
static const char *
const s =
"long";
return s; }
2321 static bool is_float() {
return false; }
2322 static bool is_inf(
const long) {
return false; }
2323 static bool is_nan(
const long) {
return false; }
2324 static long min() {
return (
long)(-1L<<(8*
sizeof(long)-1)); }
2325 static long max() {
return ~((long)(-1L<<(8*
sizeof(
long)-1))); }
2326 static long inf() {
return max(); }
2327 static long cut(
const double val) {
return val<(double)min()?min():val>(double)max()?max():(long)val; }
2328 static const char* format() {
return "%ld"; }
2329 static long format(
const long val) {
return val; }
2333 static const char* string() {
static const char *
const s =
"double";
return s; }
2334 static bool is_float() {
return true; }
2335 static bool is_inf(
const double val) {
return !is_nan(val) && val+1==val; }
2336 static bool is_nan(
const double val) {
return !(val<=0 || val>=0); }
2337 static double min() {
return -1.7E308; }
2338 static double max() {
return 1.7E308; }
2339 static double inf() {
return max()*max(); }
2340 static double nan() {
static const double val_nan = -std::sqrt(-1.0);
return val_nan; }
2341 static double cut(
const double val) {
return val<min()?min():val>max()?max():val; }
2342 static const char* format() {
return "%.16g"; }
2343 static double format(
const double val) {
return val; }
2347 static const char* string() {
static const char *
const s =
"float";
return s; }
2348 static bool is_float() {
return true; }
2351 static float min() {
return -3.4E38f; }
2352 static float max() {
return 3.4E38f; }
2355 static float cut(
const double val) {
return val<(double)min()?min():val>(double)max()?max():(float)val; }
2356 static const char* format() {
return "%.16g"; }
2357 static double format(
const float val) {
return (
double)val; }
2360 template<
typename T,
typename t>
struct superset {
typedef T type; };
2361 template<>
struct superset<
bool,unsigned char> {
typedef unsigned char type; };
2363 template<>
struct superset<
bool,signed char> {
typedef signed char type; };
2364 template<>
struct superset<
bool,unsigned short> {
typedef unsigned short type; };
2366 template<>
struct superset<
bool,unsigned int> {
typedef unsigned int type; };
2368 template<>
struct superset<
bool,unsigned long> {
typedef unsigned long type; };
2372 template<>
struct superset<unsigned char,char> {
typedef short type; };
2373 template<>
struct superset<unsigned char,signed char> {
typedef short type; };
2374 template<>
struct superset<unsigned char,unsigned short> {
typedef unsigned short type; };
2375 template<>
struct superset<unsigned char,short> {
typedef short type; };
2376 template<>
struct superset<unsigned char,unsigned int> {
typedef unsigned int type; };
2377 template<>
struct superset<unsigned char,int> {
typedef int type; };
2378 template<>
struct superset<unsigned char,unsigned long> {
typedef unsigned long type; };
2379 template<>
struct superset<unsigned char,long> {
typedef long type; };
2380 template<>
struct superset<unsigned char,float> {
typedef float type; };
2381 template<>
struct superset<unsigned char,double> {
typedef double type; };
2382 template<>
struct superset<signed char,unsigned char> {
typedef short type; };
2383 template<>
struct superset<signed char,char> {
typedef short type; };
2384 template<>
struct superset<signed char,unsigned short> {
typedef int type; };
2385 template<>
struct superset<signed char,short> {
typedef short type; };
2386 template<>
struct superset<signed char,unsigned int> {
typedef long type; };
2387 template<>
struct superset<signed char,int> {
typedef int type; };
2388 template<>
struct superset<signed char,unsigned long> {
typedef long type; };
2389 template<>
struct superset<signed char,long> {
typedef long type; };
2390 template<>
struct superset<signed char,float> {
typedef float type; };
2391 template<>
struct superset<signed char,double> {
typedef double type; };
2392 template<>
struct superset<char,unsigned char> {
typedef short type; };
2393 template<>
struct superset<char,signed char> {
typedef short type; };
2394 template<>
struct superset<char,unsigned short> {
typedef int type; };
2395 template<>
struct superset<char,short> {
typedef short type; };
2396 template<>
struct superset<char,unsigned int> {
typedef long type; };
2397 template<>
struct superset<char,int> {
typedef int type; };
2398 template<>
struct superset<char,unsigned long> {
typedef long type; };
2399 template<>
struct superset<char,long> {
typedef long type; };
2400 template<>
struct superset<char,float> {
typedef float type; };
2401 template<>
struct superset<char,double> {
typedef double type; };
2402 template<>
struct superset<unsigned short,char> {
typedef int type; };
2403 template<>
struct superset<unsigned short,signed char> {
typedef int type; };
2404 template<>
struct superset<unsigned short,short> {
typedef int type; };
2405 template<>
struct superset<unsigned short,unsigned int> {
typedef unsigned int type; };
2406 template<>
struct superset<unsigned short,int> {
typedef int type; };
2407 template<>
struct superset<unsigned short,unsigned long> {
typedef unsigned long type; };
2408 template<>
struct superset<unsigned short,long> {
typedef long type; };
2409 template<>
struct superset<unsigned short,float> {
typedef float type; };
2410 template<>
struct superset<unsigned short,double> {
typedef double type; };
2411 template<>
struct superset<short,unsigned short> {
typedef int type; };
2412 template<>
struct superset<short,unsigned int> {
typedef long type; };
2413 template<>
struct superset<short,int> {
typedef int type; };
2414 template<>
struct superset<short,unsigned long> {
typedef long type; };
2415 template<>
struct superset<short,long> {
typedef long type; };
2416 template<>
struct superset<short,float> {
typedef float type; };
2417 template<>
struct superset<short,double> {
typedef double type; };
2418 template<>
struct superset<unsigned int,char> {
typedef long type; };
2419 template<>
struct superset<unsigned int,signed char> {
typedef long type; };
2420 template<>
struct superset<unsigned int,short> {
typedef long type; };
2421 template<>
struct superset<unsigned int,int> {
typedef long type; };
2422 template<>
struct superset<unsigned int,unsigned long> {
typedef unsigned long type; };
2423 template<>
struct superset<unsigned int,long> {
typedef long type; };
2424 template<>
struct superset<unsigned int,float> {
typedef float type; };
2425 template<>
struct superset<unsigned int,double> {
typedef double type; };
2426 template<>
struct superset<int,unsigned int> {
typedef long type; };
2427 template<>
struct superset<int,unsigned long> {
typedef long type; };
2428 template<>
struct superset<int,long> {
typedef long type; };
2429 template<>
struct superset<int,float> {
typedef float type; };
2430 template<>
struct superset<int,double> {
typedef double type; };
2431 template<>
struct superset<unsigned long,char> {
typedef long type; };
2432 template<>
struct superset<unsigned long,signed char> {
typedef long type; };
2433 template<>
struct superset<unsigned long,short> {
typedef long type; };
2434 template<>
struct superset<unsigned long,int> {
typedef long type; };
2435 template<>
struct superset<unsigned long,long> {
typedef long type; };
2436 template<>
struct superset<unsigned long,float> {
typedef float type; };
2437 template<>
struct superset<unsigned long,double> {
typedef double type; };
2438 template<>
struct superset<long,float> {
typedef float type; };
2439 template<>
struct superset<long,double> {
typedef double type; };
2440 template<>
struct superset<float,double> {
typedef double type; };
2442 template<
typename t1,
typename t2,
typename t3>
struct superset2 {
2446 template<
typename t1,
typename t2,
typename t3,
typename t4>
struct superset3 {
2450 template<
typename t1,
typename t2>
struct last {
typedef t2 type; };
2452 #define _cimg_Tt typename cimg::superset<T,t>::type
2453 #define _cimg_Tfloat typename cimg::superset<T,float>::type
2454 #define _cimg_Ttfloat typename cimg::superset2<T,t,float>::type
2455 #define _cimg_Ttdouble typename cimg::superset2<T,t,double>::type
2460 volatile unsigned int nb_wins;
2461 pthread_t* event_thread;
2464 unsigned int nb_bits;
2466 bool is_shm_enabled;
2468 #ifdef cimg_use_xrandr
2469 XRRScreenSize *resolutions;
2470 Rotation curr_rotation;
2471 unsigned int curr_resolution;
2472 unsigned int nb_resolutions;
2474 X11_info():nb_wins(0),event_thread(0),display(0),
2475 nb_bits(0),is_blue_first(false),is_shm_enabled(false),byte_order(false) {
2476 #ifdef cimg_use_xrandr
2479 curr_resolution = nb_resolutions = 0;
2483 #if defined(cimg_module)
2484 X11_info& X11_attr();
2485 #elif defined(cimg_main)
2486 X11_info& X11_attr() {
static X11_info val;
return val; }
2488 inline X11_info& X11_attr() {
static X11_info val;
return val; }
2491 #elif cimg_display==2
2494 Win32_info() { wait_event = CreateEvent(0,FALSE,FALSE,0); }
2496 #if defined(cimg_module)
2497 Win32_info& Win32_attr();
2498 #elif defined(cimg_main)
2499 Win32_info& Win32_attr() {
static Win32_info val;
return val; }
2501 inline Win32_info& Win32_attr() {
static Win32_info val;
return val; }
2505 #if defined(cimg_use_magick)
2506 static struct Magick_info {
2508 Magick::InitializeMagick(
"");
2515 const unsigned int keyESC = XK_Escape;
2516 const unsigned int keyF1 = XK_F1;
2517 const unsigned int keyF2 = XK_F2;
2518 const unsigned int keyF3 = XK_F3;
2519 const unsigned int keyF4 = XK_F4;
2520 const unsigned int keyF5 = XK_F5;
2521 const unsigned int keyF6 = XK_F6;
2522 const unsigned int keyF7 = XK_F7;
2523 const unsigned int keyF8 = XK_F8;
2524 const unsigned int keyF9 = XK_F9;
2525 const unsigned int keyF10 = XK_F10;
2526 const unsigned int keyF11 = XK_F11;
2527 const unsigned int keyF12 = XK_F12;
2528 const unsigned int keyPAUSE = XK_Pause;
2529 const unsigned int key1 = XK_1;
2530 const unsigned int key2 = XK_2;
2531 const unsigned int key3 = XK_3;
2532 const unsigned int key4 = XK_4;
2533 const unsigned int key5 = XK_5;
2534 const unsigned int key6 = XK_6;
2535 const unsigned int key7 = XK_7;
2536 const unsigned int key8 = XK_8;
2537 const unsigned int key9 = XK_9;
2538 const unsigned int key0 = XK_0;
2540 const unsigned int keyINSERT = XK_Insert;
2541 const unsigned int keyHOME = XK_Home;
2542 const unsigned int keyPAGEUP = XK_Page_Up;
2543 const unsigned int keyTAB = XK_Tab;
2544 const unsigned int keyQ = XK_q;
2545 const unsigned int keyW = XK_w;
2546 const unsigned int keyE = XK_e;
2547 const unsigned int keyR = XK_r;
2548 const unsigned int keyT = XK_t;
2549 const unsigned int keyY = XK_y;
2550 const unsigned int keyU = XK_u;
2551 const unsigned int keyI = XK_i;
2552 const unsigned int keyO = XK_o;
2553 const unsigned int keyP = XK_p;
2554 const unsigned int keyDELETE = XK_Delete;
2555 const unsigned int keyEND = XK_End;
2558 const unsigned int keyA = XK_a;
2559 const unsigned int keyS = XK_s;
2560 const unsigned int keyD = XK_d;
2561 const unsigned int keyF = XK_f;
2562 const unsigned int keyG = XK_g;
2563 const unsigned int keyH = XK_h;
2564 const unsigned int keyJ = XK_j;
2565 const unsigned int keyK = XK_k;
2566 const unsigned int keyL = XK_l;
2567 const unsigned int keyENTER = XK_Return;
2569 const unsigned int keyZ = XK_z;
2570 const unsigned int keyX = XK_x;
2571 const unsigned int keyC = XK_c;
2572 const unsigned int keyV = XK_v;
2573 const unsigned int keyB = XK_b;
2574 const unsigned int keyN = XK_n;
2575 const unsigned int keyM = XK_m;
2580 const unsigned int keyALT = XK_Alt_L;
2581 const unsigned int keySPACE = XK_space;
2582 const unsigned int keyALTGR = XK_Alt_R;
2584 const unsigned int keyMENU = XK_Menu;
2589 const unsigned int keyPAD0 = XK_KP_0;
2590 const unsigned int keyPAD1 = XK_KP_1;
2591 const unsigned int keyPAD2 = XK_KP_2;
2592 const unsigned int keyPAD3 = XK_KP_3;
2593 const unsigned int keyPAD4 = XK_KP_4;
2594 const unsigned int keyPAD5 = XK_KP_5;
2595 const unsigned int keyPAD6 = XK_KP_6;
2596 const unsigned int keyPAD7 = XK_KP_7;
2597 const unsigned int keyPAD8 = XK_KP_8;
2598 const unsigned int keyPAD9 = XK_KP_9;
2599 const unsigned int keyPADADD = XK_KP_Add;
2600 const unsigned int keyPADSUB = XK_KP_Subtract;
2601 const unsigned int keyPADMUL = XK_KP_Multiply;
2602 const unsigned int keyPADDIV = XK_KP_Divide;
2604 #elif cimg_display==2
2606 const unsigned int keyESC = VK_ESCAPE;
2607 const unsigned int keyF1 = VK_F1;
2608 const unsigned int keyF2 = VK_F2;
2609 const unsigned int keyF3 = VK_F3;
2610 const unsigned int keyF4 = VK_F4;
2611 const unsigned int keyF5 = VK_F5;
2612 const unsigned int keyF6 = VK_F6;
2613 const unsigned int keyF7 = VK_F7;
2614 const unsigned int keyF8 = VK_F8;
2615 const unsigned int keyF9 = VK_F9;
2616 const unsigned int keyF10 = VK_F10;
2617 const unsigned int keyF11 = VK_F11;
2618 const unsigned int keyF12 = VK_F12;
2619 const unsigned int keyPAUSE = VK_PAUSE;
2620 const unsigned int key1 =
'1';
2621 const unsigned int key2 =
'2';
2622 const unsigned int key3 =
'3';
2623 const unsigned int key4 =
'4';
2624 const unsigned int key5 =
'5';
2625 const unsigned int key6 =
'6';
2626 const unsigned int key7 =
'7';
2627 const unsigned int key8 =
'8';
2628 const unsigned int key9 =
'9';
2629 const unsigned int key0 =
'0';
2631 const unsigned int keyINSERT = VK_INSERT;
2632 const unsigned int keyHOME = VK_HOME;
2633 const unsigned int keyPAGEUP = VK_PRIOR;
2634 const unsigned int keyTAB = VK_TAB;
2635 const unsigned int keyQ =
'Q';
2636 const unsigned int keyW =
'W';
2637 const unsigned int keyE =
'E';
2638 const unsigned int keyR =
'R';
2639 const unsigned int keyT =
'T';
2640 const unsigned int keyY =
'Y';
2641 const unsigned int keyU =
'U';
2642 const unsigned int keyI =
'I';
2643 const unsigned int keyO =
'O';
2644 const unsigned int keyP =
'P';
2645 const unsigned int keyDELETE = VK_DELETE;
2646 const unsigned int keyEND = VK_END;
2649 const unsigned int keyA =
'A';
2650 const unsigned int keyS =
'S';
2651 const unsigned int keyD =
'D';
2652 const unsigned int keyF =
'F';
2653 const unsigned int keyG =
'G';
2654 const unsigned int keyH =
'H';
2655 const unsigned int keyJ =
'J';
2656 const unsigned int keyK =
'K';
2657 const unsigned int keyL =
'L';
2658 const unsigned int keyENTER = VK_RETURN;
2660 const unsigned int keyZ =
'Z';
2661 const unsigned int keyX =
'X';
2662 const unsigned int keyC =
'C';
2663 const unsigned int keyV =
'V';
2664 const unsigned int keyB =
'B';
2665 const unsigned int keyN =
'N';
2666 const unsigned int keyM =
'M';
2671 const unsigned int keyALT = VK_LMENU;
2672 const unsigned int keySPACE = VK_SPACE;
2673 const unsigned int keyALTGR = VK_CONTROL;
2675 const unsigned int keyMENU = VK_APPS;
2680 const unsigned int keyPAD0 = 0x60;
2681 const unsigned int keyPAD1 = 0x61;
2682 const unsigned int keyPAD2 = 0x62;
2683 const unsigned int keyPAD3 = 0x63;
2684 const unsigned int keyPAD4 = 0x64;
2685 const unsigned int keyPAD5 = 0x65;
2686 const unsigned int keyPAD6 = 0x66;
2687 const unsigned int keyPAD7 = 0x67;
2688 const unsigned int keyPAD8 = 0x68;
2689 const unsigned int keyPAD9 = 0x69;
2691 const unsigned int keyPADSUB = VK_SUBTRACT;
2692 const unsigned int keyPADMUL = VK_MULTIPLY;
2693 const unsigned int keyPADDIV = VK_DIVIDE;
2788 const double PI = 3.14159265358979323846;
2791 const unsigned int font10x13[256*10*13/32] = {
2792 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
2793 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80100c0,
2794 0x68000300,0x801,0xc00010,0x100c000,0x68100,0x100c0680,0x2,0x403000,0x1000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
2795 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
2796 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfc,0x0,0x0,0x0,0x0,0x0,0x4020120,
2797 0x58120480,0x402,0x1205008,0x2012050,0x58080,0x20120581,0x40000001,0x804812,0x2000000,0x0,0x300,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
2798 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x140,0x80000,0x200402,0x800000,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
2799 0x0,0x7010,0x7000000,0x8000200,0x20000,0xc0002000,0x8008,0x0,0x0,0x0,0x0,0x808,0x4000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
2800 0x0,0x0,0x80000000,0x0,0x0,0x0,0x40000,0x0,0x0,0x0,0x0,0x480,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x70,0x80100c0,0x68000480,0x1001,
2801 0xc00010,0x1018000,0x68100,0x100c0680,0x4,0x403000,0x1020000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20140,0x28081883,0x200801,
2802 0x2a00000,0x10,0x1c0201c0,0x70040f80,0xc0f81c07,0x0,0x70,0x3e0303c0,0x3c3c0f83,0xe03c2107,0xe08810,0x18c31070,0x3c0703c0,
2803 0x783e0842,0x22222208,0x83e04010,0x1008000,0x4000200,0x20001,0x2002,0x408008,0x0,0x0,0x100000,0x0,0x1008,0x2000000,0x0,0x0,0x0,
2804 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20080,0x38000880,0x8078140f,0x81c00000,0x3e000,0xc020180,0x60080001,0xe0000002,0xc00042,0x108e2010,
2805 0xc0300c0,0x300c0303,0xf83c3e0f,0x83e0f81c,0x701c070,0x3c0c41c0,0x701c0701,0xc0001d08,0x42108421,0x8820088,0x4020120,0x58140480,
2806 0x802,0x1205008,0x3014050,0xc058080,0x20120581,0x40000002,0x804814,0x2020050,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20140,
2807 0x281e2484,0x80200801,0x1c02000,0x10,0x22060220,0x880c0801,0x82208,0x80000001,0x20008,0x41030220,0x40220802,0x402102,0x209010,
2808 0x18c31088,0x22088220,0x80080842,0x22222208,0x80204010,0x1014000,0x200,0x20001,0x2000,0x8008,0x0,0x0,0x100000,0x0,0x1008,
2809 0x2000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x40000500,0x80800010,0x40200000,0x41000,0x12020040,0x10000003,0xa0000006,
2810 0x12000c4,0x31014000,0xc0300c0,0x300c0302,0x80402008,0x2008008,0x2008020,0x220c4220,0x88220882,0x20002208,0x42108421,0x8820088,
2811 0x0,0x300,0x0,0x0,0x0,0x14000000,0x0,0x200200,0x0,0x20000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,0xfc282504,0x80001000,
2812 0x82a02000,0x20,0x22020020,0x8140802,0x102208,0x80801006,0x18008,0x9c848220,0x80210802,0x802102,0x20a010,0x15429104,0x22104220,
2813 0x80080842,0x22221405,0x404008,0x1022000,0x703c0,0x381e0701,0xc0783c02,0xc09008,0x1d83c070,0x3c078140,0x381c0882,0x21242208,
2814 0x81e01008,0x2000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x201e0,0x40220500,0x80800027,0x20e02800,0x9c800,0x12020040,
2815 0x20000883,0xa0200002,0x120a044,0x11064010,0x12048120,0x48120484,0x80802008,0x2008008,0x2008020,0x210a4411,0x4411044,0x10884508,
2816 0x42108421,0x503c0b0,0x1c0701c0,0x701c0707,0x70381c07,0x1c07008,0x2008020,0x20f01c0,0x701c0701,0xc0201c08,0x82208822,0x883c088,
2817 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,0x50281903,0x20001000,0x80802000,0x20,0x22020040,0x30240f03,0xc0101c08,0x80801018,
2818 0x1fc06010,0xa48483c0,0x80210f03,0xe0803f02,0x20c010,0x15429104,0x22104220,0x70080841,0x41540805,0x804008,0x1041000,0x8220,
2819 0x40220881,0x882202,0x40a008,0x12422088,0x22088180,0x40100882,0x21241408,0x80201008,0x2031000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
2820 0x0,0x20280,0x401c0200,0x700028,0x21205000,0x92800,0xc1fc080,0x10000883,0xa0200002,0x1205049,0x12c19010,0x12048120,0x48120484,
2821 0xf0803c0f,0x3c0f008,0x2008020,0x790a4411,0x4411044,0x10504908,0x42108421,0x5022088,0x2008020,0x8020080,0x88402208,0x82208808,
2822 0x2008020,0x1e088220,0x88220882,0x20002608,0x82208822,0x8822088,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,0x501c0264,
2823 0xa0001000,0x8001fc00,0x7000020,0x22020080,0x83e0082,0x20202207,0x80000020,0x1020,0xa4848220,0x80210802,0x9c2102,0x20c010,
2824 0x12425104,0x3c1043c0,0x8080841,0x41540802,0x804008,0x1000000,0x78220,0x40220f81,0x882202,0x40c008,0x12422088,0x22088100,
2825 0x60100881,0x41540805,0x406008,0x1849000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20280,0xf0140200,0x880028,0x20e0a03f,0x709c800,
2826 0x201c0,0x60000881,0xa0000007,0xc0284b,0x122eb020,0x12048120,0x48120487,0x80802008,0x2008008,0x2008020,0x21094411,0x4411044,
2827 0x10204908,0x42108421,0x2022088,0x1e0781e0,0x781e0787,0xf8403e0f,0x83e0f808,0x2008020,0x22088220,0x88220882,0x21fc2a08,0x82208822,
2828 0x5022050,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20001,0xf80a0294,0x40001000,0x80002000,0x20,0x22020100,0x8040082,0x20202200,
2829 0x80000018,0x1fc06020,0xa48fc220,0x80210802,0x842102,0x20a010,0x12425104,0x20104240,0x8080841,0x41541402,0x1004008,0x1000000,
2830 0x88220,0x40220801,0x882202,0x40a008,0x12422088,0x22088100,0x18100881,0x41540805,0x801008,0x2046000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
2831 0x0,0x0,0x0,0x20280,0x401c0f80,0x80880028,0x20005001,0x94800,0x20000,0x880,0xa0000000,0x5015,0x4215040,0x3f0fc3f0,0xfc3f0fc8,
2832 0x80802008,0x2008008,0x2008020,0x21094411,0x4411044,0x10505108,0x42108421,0x203c088,0x22088220,0x88220888,0x80402008,0x2008008,
2833 0x2008020,0x22088220,0x88220882,0x20002a08,0x82208822,0x5022050,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xa00a0494,0x60001000,
2834 0x80002004,0x8020,0x22020200,0x88040882,0x20402201,0x801006,0x18000,0x9f084220,0x40220802,0x442102,0x209010,0x10423088,0x20088220,
2835 0x8080840,0x80882202,0x2004008,0x1000000,0x88220,0x40220881,0x882202,0x409008,0x12422088,0x22088100,0x8100880,0x80881402,
2836 0x1001008,0x2000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20280,0x40220200,0x80700027,0x20002801,0x92800,0x1fc000,0x980,
2837 0xa0000000,0xa017,0x84417840,0x21084210,0x84210848,0x80402008,0x2008008,0x2008020,0x2208c220,0x88220882,0x20882208,0x42108421,
2838 0x2020088,0x22088220,0x88220888,0xc8402208,0x82208808,0x2008020,0x22088220,0x88220882,0x20203208,0x82208822,0x2022020,0x0,0x0,0x0,
2839 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000,0xa03c0463,0x90000801,0x2004,0x8040,0x1c0703e0,0x70040701,0xc0401c06,0x801001,0x20020,
2840 0x400843c0,0x3c3c0f82,0x3c2107,0x1c0881e,0x10423070,0x20070210,0xf0080780,0x80882202,0x3e04004,0x1000000,0x783c0,0x381e0701,
2841 0x782202,0x408808,0x12422070,0x3c078100,0x700c0780,0x80882202,0x1e01008,0x2000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x201e0,
2842 0xf8000200,0x80080010,0x40000001,0x41000,0x0,0xe80,0xa0000000,0x21,0x8e21038,0x21084210,0x84210848,0xf83c3e0f,0x83e0f81c,
2843 0x701c070,0x3c08c1c0,0x701c0701,0xc0005c07,0x81e0781e,0x20200b0,0x1e0781e0,0x781e0787,0x30381c07,0x1c07008,0x2008020,0x1c0881c0,
2844 0x701c0701,0xc0201c07,0x81e0781e,0x203c020,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80000,0x801,0x4,0x40,0x0,0x0,0x0,0x1000,
2845 0x0,0x3c000000,0x0,0x0,0x0,0x0,0x10000,0x0,0x0,0x4004,0x1000000,0x0,0x0,0x80000,0x400000,0x0,0x20008000,0x0,0x4,0x1008,0x2000000,
2846 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x8008000f,0x80000000,0x3e000,0x0,0x800,0xa0000400,0x0,0x0,0x0,0x0,0x80000,0x0,
2847 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100000,0x0,0x0,0x0,0x0,0x2000,0x0,0x4020040,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80000,
2848 0x402,0x8,0x40,0x0,0x0,0x0,0x2000,0x0,0x0,0x0,0x0,0x0,0x0,0xc000,0x0,0x0,0x7004,0x70000fc,0x0,0x0,0x700000,0x800000,0x0,0x20008000,
2849 0x0,0x4,0x808,0x4000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x80f00000,0x0,0x0,0x0,0x800,0xa0001800,0x0,0x0,0x0,0x0,
2850 0x300000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x600000,0x0,0x0,0x0,0x0,0x0,0x0,0x4020040
2854 const unsigned int font12x24[12*24*256/32] = {
2855 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
2856 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x19,0x80000000,0x198000,0x0,0x0,0x0,0x0,
2857 0x0,0x198,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc001806,0xc81980,0x60000000,0xc001806,0x1980c00,0x18060198,0xc80c,
2858 0x180600,0xc8198000,0xc001,0x80601980,0x18000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
2859 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
2860 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf,0x0,0xf0000,0x0,0x0,0x0,0x0,0x0,0x198,0x0,0x0,0x0,0x0,0x0,0x0,
2861 0x0,0x0,0x0,0x0,0x0,0x0,0x600300f,0x1301980,0x90000000,0x600300f,0x1980600,0x300f0198,0x13006,0x300f01,0x30198000,0x6003,
2862 0xf01980,0x30000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
2863 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
2864 0x0,0x0,0x0,0x0,0x0,0x0,0x6,0x0,0x60000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7007,0x3c0000,0x3006019,
2865 0x80000000,0x90000000,0x3006019,0x80000300,0x60198000,0x3,0x601980,0x0,0x3006,0x1980000,0x60000000,0x0,0x0,0xe0000000,0x0,
2866 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
2867 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x18000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000000,
2868 0x0,0x0,0x0,0x0,0x0,0xc800019,0x80000000,0x198000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x0,0x0,0x1001,0x420000,0x0,0x0,0x90000000,
2869 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x18000c06,0xc80001,0x10000000,0x18000c06,0x1800,0xc060000,0xc818,0xc0600,0xc8000000,
2870 0x18000,0xc0600000,0xc000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6019,0x80660207,0x800f8060,0x300c004,0x0,0x6,
2871 0xe00703f,0x3f00383,0xf80f07fc,0x1f01f000,0x0,0xf8,0x607f,0x7c7e07,0xfe7fe0f8,0x6063fc1f,0x86066007,0xe7060f0,0x7f80f07f,
2872 0x81f8fff6,0x6606c03,0x70ee077f,0xe0786000,0xf0070000,0xc000060,0xc0,0x3e000,0x60006003,0x600fc00,0x0,0x0,0x0,0x0,0x0,0x3c0603,
2873 0xc0000000,0x7800000,0xf0000,0x0,0xf00001f,0x80001fe0,0x7fe000,0x0,0x0,0x0,0x168fe609,0x0,0x90e07,0x6000,0x3c000e,0x70000f8,
2874 0x1980001f,0x0,0x1f8,0xf00000f,0xf00180,0xfe000,0xe00e,0x1001,0x20060,0x6006006,0x600600,0x600fe07c,0x7fe7fe7f,0xe7fe3fc3,
2875 0xfc3fc3fc,0x7e07060f,0xf00f00,0xf00f0000,0xf360660,0x6606606e,0x76001e0,0xc00180f,0x1681981,0x10000000,0xc00180f,0x1980c00,
2876 0x180f0198,0x3801680c,0x180f01,0x68198000,0xc001,0x80f01980,0x18600198,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6019,
2877 0x8044020c,0xc01f8060,0x2004004,0x0,0xc,0x3f81f07f,0x87f80383,0xf81f87fc,0x3f83f800,0x0,0x1fc,0x780607f,0x81fe7f87,0xfe7fe1fc,
2878 0x6063fc1f,0x860c6007,0xe7061f8,0x7fc1f87f,0xc3fcfff6,0x6606c03,0x30c6067f,0xe0783000,0xf00d8000,0x6000060,0xc0,0x7e000,0x60006003,
2879 0x600fc00,0x0,0x0,0xc00,0x0,0x0,0x7c0603,0xe0000000,0xfc00000,0x1f0000,0x0,0x900003f,0xc0003fe0,0x7fe000,0x0,0x0,0x0,0x1302660f,
2880 0x0,0xf0606,0x6004,0x7e0006,0x60601f8,0x19800001,0x80000000,0x1f8,0x19800010,0x81080300,0x3f2000,0x2011,0x1001,0x1c0060,0x6006006,
2881 0x600600,0x601fe1fe,0x7fe7fe7f,0xe7fe3fc3,0xfc3fc3fc,0x7f87061f,0x81f81f81,0xf81f8000,0x3fa60660,0x66066066,0x66003f0,0x6003009,
2882 0x1301981,0x10000000,0x6003009,0x1980600,0x30090198,0x1f013006,0x300901,0x30198000,0x6003,0x901980,0x30600198,0x0,0x0,0x0,
2883 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6019,0x80cc0f8c,0xc0180060,0x6006044,0x40000000,0xc,0x3181b041,0xc41c0783,0x388018,
2884 0x71c71800,0x0,0x106,0x18c0f061,0xc38261c6,0x600384,0x60606001,0x86186007,0xe78630c,0x60e30c60,0xe7040606,0x630cc03,0x39c30c00,
2885 0xc0603000,0x3018c000,0x3000060,0xc0,0x60000,0x60000000,0x6000c00,0x0,0x0,0xc00,0x0,0x0,0x600600,0x60000000,0x18400000,0x180000,
2886 0x0,0x19800070,0x40003600,0xc000,0x0,0x0,0x0,0x25a06,0x0,0x6030c,0x4,0xe20007,0xe060180,0xf000,0x80000000,0xf0000,0x10800000,
2887 0x80080600,0x7f2000,0x2020,0x80001001,0x20000,0xf00f00f,0xf00f00,0x601b0382,0x60060060,0x6000600,0x60060060,0x61c78630,0xc30c30c3,
2888 0xc30c000,0x30e60660,0x66066063,0xc600738,0x3006019,0x80000000,0xe0000000,0x3006019,0x80000300,0x60198000,0x3e000003,0x601980,
2889 0x0,0x3006,0x1980000,0x60600000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6019,0x80cc1fcc,0xc0180060,0x6006035,0x80000000,
2890 0x18,0x71c03000,0xc00c0583,0x300018,0x60c60c00,0x0,0x6,0x3060f060,0xc30060c6,0x600300,0x60606001,0x86306007,0x9e78670e,0x60670e60,
2891 0x66000606,0x630c606,0x19830c01,0xc0601800,0x30306000,0x60,0xc0,0x60000,0x60000000,0x6000c00,0x0,0x0,0xc00,0x0,0x0,0x600600,
2892 0x60000000,0x18000000,0x300000,0x0,0x78060,0x6600,0x1c000,0x300c,0x39819c0,0x0,0x25a00,0x0,0x30c,0x4,0xc00003,0xc060180,0x30c1f,
2893 0x80000000,0x30c000,0x10800001,0x80700000,0x7f2000,0x2020,0x80001001,0x20060,0xf00f00f,0xf00f00,0xf01b0300,0x60060060,0x6000600,
2894 0x60060060,0x60c78670,0xe70e70e7,0xe70e000,0x70c60660,0x66066063,0xc7f8618,0x0,0x0,0x0,0x0,0x0,0x0,0x7000000,0x0,0x0,0x0,
2895 0x0,0x600000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6019,0x87ff3a4c,0xc0180060,0x400600e,0x600000,0x18,0x60c03000,
2896 0xc00c0d83,0x700018,0x60c60c00,0x20,0x400006,0x3060f060,0xc6006066,0x600600,0x60606001,0x86606006,0x966c6606,0x60660660,0x66000606,
2897 0x630c666,0xf019801,0x80601800,0x30603000,0x1f06f,0xf01ec0,0xf03fe1ec,0x6703e01f,0x61c0c06,0xdc6701f0,0x6f01ec0c,0xe1f87fc6,
2898 0xc60cc03,0x71c60c7f,0xc0600600,0x60000000,0x30000000,0x300000,0x40040,0x88060,0x6600,0x18000,0x300c,0x1981980,0x0,0x2421f,
2899 0x80003ce0,0x7fc198,0x601f,0xc02021,0x980600c0,0x40230,0x80000000,0x402000,0x19806003,0x80006,0xc7f2000,0x2020,0x80001001,
2900 0x420060,0xf00f00f,0xf00f00,0xf01b0600,0x60060060,0x6000600,0x60060060,0x6066c660,0x66066066,0x6606208,0x60e60660,0x66066061,
2901 0x987fc670,0x1f01f01f,0x1f01f01,0xf039c0f0,0xf00f00f,0xf03e03,0xe03e03e0,0x1f06701f,0x1f01f01,0xf01f0060,0x1e660c60,0xc60c60c6,
2902 0xc6f060c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x7ff3207,0x8c0c0000,0xc00300e,0x600000,0x30,0x60c03000,
2903 0xc01c0983,0xf0600030,0x31860c06,0x6001e0,0x78000e,0x23e1f861,0xc6006066,0x600600,0x60606001,0x86c06006,0x966c6606,0x60660660,
2904 0xe7000606,0x630c666,0xf01f803,0x600c00,0x30000000,0x3f87f,0x83f83fc3,0xf83fe3fc,0x7f83e01f,0x6380c07,0xfe7f83f8,0x7f83fc0d,
2905 0xf3fc7fc6,0xc71cc03,0x3183187f,0xc0600600,0x60000000,0xff806000,0x300000,0x40040,0x88070,0x6600,0x60030060,0x6001818,0x1883180,
2906 0x0,0x2423f,0xc0007ff0,0x607fc1f8,0x603f,0x80c01fc1,0xf80601e0,0x5f220,0x80420000,0x5f2000,0xf006006,0x80006,0xc7f2000,0x2020,
2907 0x82107c07,0xc03c0060,0x1f81f81f,0x81f81f80,0xf03b0600,0x60060060,0x6000600,0x60060060,0x6066c660,0x66066066,0x660671c,0x61660660,
2908 0x66066061,0xf860e6c0,0x3f83f83f,0x83f83f83,0xf87fe3f8,0x3f83f83f,0x83f83e03,0xe03e03e0,0x3f87f83f,0x83f83f83,0xf83f8060,
2909 0x3fc60c60,0xc60c60c3,0x187f8318,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x883200,0x300c0000,0xc003035,0x80600000,
2910 0x30,0x66c03001,0xc0f81983,0xf86f0030,0x1f071c06,0x600787,0xfe1e001c,0x6261987f,0x86006067,0xfe7fc600,0x7fe06001,0x87c06006,
2911 0xf6646606,0x60e6067f,0xc3e00606,0x61986f6,0x600f007,0x600c00,0x30000000,0x21c71,0x830831c3,0x1c06031c,0x71c06003,0x6700c06,
2912 0x6671c318,0x71831c0f,0x16040c06,0xc318606,0x1b031803,0x80600600,0x60000000,0x30009000,0x300000,0x40040,0x7003e,0x67e0,0x90070090,
2913 0x9001818,0x8c3100,0x0,0x60,0x4000e730,0x900380f0,0x6034,0x80c018c7,0xfe060338,0xb0121,0x80c60000,0x909000,0x6008,0x1080006,
2914 0xc3f2000,0x2011,0x3180060,0x60060e0,0x19819819,0x81981981,0x9833c600,0x7fe7fe7f,0xe7fe0600,0x60060060,0x60664660,0x66066066,
2915 0x66063b8,0x62660660,0x66066060,0xf06066c0,0x21c21c21,0xc21c21c2,0x1c466308,0x31c31c31,0xc31c0600,0x60060060,0x31871c31,0x83183183,
2916 0x18318000,0x71860c60,0xc60c60c3,0x18718318,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x1981a00,0xe03e0000,0xc003044,
2917 0x40600000,0x60,0x66c03001,0x80f03182,0x1c7f8030,0x3f83fc06,0x601e07,0xfe078038,0x6661987f,0x86006067,0xfe7fc61e,0x7fe06001,
2918 0x87e06006,0x66666606,0x7fc6067f,0x81f80606,0x61986f6,0x6006006,0x600600,0x30000000,0xc60,0xc60060c6,0xc06060c,0x60c06003,
2919 0x6e00c06,0x6660c60c,0x60c60c0e,0x6000c06,0xc318666,0x1f031803,0x600600,0x603c2000,0x30016800,0x1fe0000,0x1f81f8,0x1c1f,0x804067e1,
2920 0x68060168,0x16800810,0xc42300,0x0,0x60,0x20c331,0x68030060,0x6064,0x3fc1040,0xf006031c,0xa011e,0x818c7fe0,0x909000,0x7fe1f,
2921 0x80f00006,0xc0f2060,0xf80e,0x18c0780,0x780781c0,0x19819819,0x81981981,0x9833c600,0x7fe7fe7f,0xe7fe0600,0x60060060,0xfc666660,
2922 0x66066066,0x66061f0,0x66660660,0x66066060,0x606066e0,0xc00c00,0xc00c00c0,0xc066600,0x60c60c60,0xc60c0600,0x60060060,0x60c60c60,
2923 0xc60c60c6,0xc60c000,0x61c60c60,0xc60c60c3,0x1860c318,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x1980f81,0x80373000,
2924 0xc003004,0x7fe0001,0xf0000060,0x60c03003,0x183180,0xc71c060,0x3181ec00,0x7000,0xe070,0x66619860,0xc6006066,0x60061e,0x60606001,
2925 0x87606006,0x66626606,0x7f860661,0xc01c0606,0x6198696,0xf00600e,0x600600,0x30000000,0x1fc60,0xc60060c7,0xfc06060c,0x60c06003,
2926 0x7c00c06,0x6660c60c,0x60c60c0c,0x7f00c06,0xc3b8666,0xe01b007,0x3c00600,0x3c7fe000,0xff03ec00,0x1fe0000,0x40040,0xe001,0xc0806603,
2927 0xec0e03ec,0x3ec00010,0x0,0x60000000,0x7f,0x10c3f3,0xec070060,0x6064,0x3fc1040,0x6000030c,0xa0100,0x3187fe1,0xf09f1000,0x7fe00,
2928 0x6,0xc012060,0x0,0xc63c03,0xc03c0380,0x19819819,0x81981981,0x98330600,0x60060060,0x6000600,0x60060060,0xfc662660,0x66066066,
2929 0x66060e0,0x6c660660,0x66066060,0x6060e630,0x1fc1fc1f,0xc1fc1fc1,0xfc3fe600,0x7fc7fc7f,0xc7fc0600,0x60060060,0x60c60c60,0xc60c60c6,
2930 0xc60c7fe,0x62c60c60,0xc60c60c1,0xb060c1b0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0xffe02c6,0x3c633000,0xc003004,
2931 0x7fe0001,0xf00000c0,0x60c03006,0xc6180,0xc60c060,0x60c00c00,0x7000,0xe060,0x66639c60,0x66006066,0x600606,0x60606001,0x86306006,
2932 0x66636606,0x60060660,0xc0060606,0x61f8696,0xf00600c,0x600300,0x30000000,0x3fc60,0xc60060c7,0xfc06060c,0x60c06003,0x7c00c06,
2933 0x6660c60c,0x60c60c0c,0x1f80c06,0xc1b0666,0xe01b00e,0x3c00600,0x3c43c000,0x3007de00,0x600000,0x40040,0x30000,0x61006607,0xde0c07de,
2934 0x7de00000,0x0,0xf07fefff,0x1f,0x8008c3f7,0xde0e0060,0x6064,0xc01047,0xfe00018c,0xb013f,0x86300061,0xf0911000,0x6000,0x6,
2935 0xc012060,0x3f,0x8063c0cc,0x3cc0c700,0x39c39c39,0xc39c39c1,0x98630600,0x60060060,0x6000600,0x60060060,0x60663660,0x66066066,
2936 0x66061f0,0x78660660,0x66066060,0x607fc618,0x3fc3fc3f,0xc3fc3fc3,0xfc7fe600,0x7fc7fc7f,0xc7fc0600,0x60060060,0x60c60c60,0xc60c60c6,
2937 0xc60c7fe,0x64c60c60,0xc60c60c1,0xb060c1b0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0xffe0260,0x6661b000,0xc003000,
2938 0x600000,0xc0,0x60c0300c,0xc7fe0,0xc60c060,0x60c01c00,0x1e07,0xfe078060,0x6663fc60,0x66006066,0x600606,0x60606001,0x86386006,
2939 0x6636606,0x60060660,0xe0060606,0x60f039c,0x1b806018,0x600300,0x30000000,0x70c60,0xc60060c6,0x6060c,0x60c06003,0x7600c06,
2940 0x6660c60c,0x60c60c0c,0x1c0c06,0xc1b03fc,0xe01f01c,0xe00600,0x70000000,0x3007fc00,0x600000,0x40040,0x0,0x62006607,0xfc1807fc,
2941 0x7fc00000,0x0,0xf0000000,0x1,0xc004c307,0xfc1c0060,0x6064,0xc018c0,0x600000d8,0x5f200,0x3180060,0x50a000,0x6000,0x6,0xc012000,
2942 0x0,0xc601c0,0x4201c600,0x3fc3fc3f,0xc3fc3fc3,0xfc7f0600,0x60060060,0x6000600,0x60060060,0x60663660,0x66066066,0x66063b8,
2943 0x70660660,0x66066060,0x607f860c,0x70c70c70,0xc70c70c7,0xcc60600,0x60060060,0x6000600,0x60060060,0x60c60c60,0xc60c60c6,0xc60c000,
2944 0x68c60c60,0xc60c60c1,0xf060c1f0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3300260,0x6661e000,0xc003000,0x600000,
2945 0x180,0x71c03018,0xc7fe0,0xc60c0c0,0x60c01800,0x787,0xfe1e0060,0x6663fc60,0x630060c6,0x600306,0x60606001,0x86186006,0x661e70e,
2946 0x60070c60,0x60060606,0x60f039c,0x19806038,0x600180,0x30000000,0x60c60,0xc60060c6,0x6060c,0x60c06003,0x6700c06,0x6660c60c,
2947 0x60c60c0c,0xc0c06,0xc1b039c,0x1f00e018,0x600600,0x60000000,0x1803f800,0x600000,0x40040,0x39e00,0x63006603,0xf83803f8,0x3f800000,
2948 0x0,0x60000000,0x0,0xc00cc303,0xf8180060,0x6064,0xc01fc0,0x60060070,0x40200,0x18c0060,0x402000,0x6000,0x6,0xc012000,0x0,0x18c0140,
2949 0x2014600,0x3fc3fc3f,0xc3fc3fc3,0xfc7f0300,0x60060060,0x6000600,0x60060060,0x60c61e70,0xe70e70e7,0xe70e71c,0x60e60660,0x66066060,
2950 0x6060060c,0x60c60c60,0xc60c60c6,0xcc60600,0x60060060,0x6000600,0x60060060,0x60c60c60,0xc60c60c6,0xc60c000,0x70c60c60,0xc60c60c0,
2951 0xe060c0e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x33022e0,0x6670c000,0xc003000,0x600600,0x60180,0x31803030,
2952 0x41c0184,0x1831c0c0,0x71c23806,0x6001e0,0x780000,0x62630c60,0xe38261c6,0x600386,0x60606043,0x860c6006,0x661e30c,0x60030c60,
2953 0x740e0607,0xe0f039c,0x31c06030,0x600180,0x30000000,0x61c71,0x830831c3,0x406031c,0x60c06003,0x6300c06,0x6660c318,0x71831c0c,
2954 0x41c0c07,0x1c0e039c,0x1b00e030,0x600600,0x60000000,0x1c41b00e,0x601cc0,0x401f8,0x45240,0xe1803601,0xb03001b0,0x1b000000,
2955 0x0,0x0,0x41,0xc008e711,0xb0300060,0x6034,0x80c02020,0x60060030,0x30c00,0xc60000,0x30c000,0x0,0x7,0x1c012000,0x0,0x3180240,
2956 0x6024608,0x30c30c30,0xc30c30c3,0xc630382,0x60060060,0x6000600,0x60060060,0x61c61e30,0xc30c30c3,0xc30c208,0x70c70e70,0xe70e70e0,
2957 0x6060068c,0x61c61c61,0xc61c61c6,0x1cc62308,0x30430430,0x43040600,0x60060060,0x31860c31,0x83183183,0x18318060,0x31c71c71,
2958 0xc71c71c0,0xe07180e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x2203fc0,0x663f6000,0x6006000,0x600600,0x60300,
2959 0x3f81fe7f,0xc7f80187,0xf83f80c0,0x3f83f006,0x600020,0x400060,0x33e6067f,0xc1fe7f87,0xfe6001fe,0x6063fc7f,0x60e7fe6,0x660e3f8,
2960 0x6001f860,0x37fc0603,0xfc06030c,0x30c0607f,0xe06000c0,0x30000000,0x7fc7f,0x83f83fc3,0xfc0603fc,0x60c7fe03,0x61807c6,0x6660c3f8,
2961 0x7f83fc0c,0x7f80fc3,0xfc0e039c,0x3180607f,0xc0600600,0x60000000,0xfc0e00c,0x601986,0x66040040,0x4527f,0xc0803fe0,0xe07fe0e0,
2962 0xe000000,0x0,0x0,0x7f,0x80107ff0,0xe07fc060,0x603f,0x83fe0000,0x60060018,0xf000,0x420000,0xf0000,0x7fe00,0x7,0xfe012000,
2963 0x0,0x2100640,0xc0643f8,0x60660660,0x66066067,0xec3e1fe,0x7fe7fe7f,0xe7fe3fc3,0xfc3fc3fc,0x7f860e3f,0x83f83f83,0xf83f8000,
2964 0x5fc3fc3f,0xc3fc3fc0,0x606006fc,0x7fc7fc7f,0xc7fc7fc7,0xfcffe3f8,0x3fc3fc3f,0xc3fc7fe7,0xfe7fe7fe,0x3f860c3f,0x83f83f83,
2965 0xf83f8060,0x7f83fc3f,0xc3fc3fc0,0x607f8060,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6000,0x2201f80,0x3c1e7000,0x6006000,
2966 0x600,0x60300,0xe01fe7f,0xc3f00183,0xe01f0180,0x1f01e006,0x600000,0x60,0x3006067f,0x807c7e07,0xfe6000f8,0x6063fc3e,0x6067fe6,
2967 0x660e0f0,0x6000f060,0x3bf80601,0xf806030c,0x60e0607f,0xe06000c0,0x30000000,0x1ec6f,0xf01ec0,0xf80601ec,0x60c7fe03,0x61c03c6,
2968 0x6660c1f0,0x6f01ec0c,0x3f007c1,0xcc0e030c,0x71c0c07f,0xc0600600,0x60000000,0x7804018,0xe01186,0x66040040,0x39e3f,0x80401fe0,
2969 0x407fe040,0x4000000,0x0,0x0,0x3f,0x203ce0,0x407fc060,0x601f,0x3fe0000,0x60060018,0x0,0x0,0x0,0x7fe00,0x6,0xe6012000,0x0,
2970 0x7e0,0x1807e1f0,0x60660660,0x66066066,0x6c3e07c,0x7fe7fe7f,0xe7fe3fc3,0xfc3fc3fc,0x7e060e0f,0xf00f00,0xf00f0000,0x8f01f81f,
2971 0x81f81f80,0x60600670,0x1ec1ec1e,0xc1ec1ec1,0xec79c0f0,0xf80f80f,0x80f87fe7,0xfe7fe7fe,0x1f060c1f,0x1f01f01,0xf01f0000,0x4f01cc1c,
2972 0xc1cc1cc0,0xc06f00c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x200,0x0,0x6006000,0x600,0x600,0x0,0x0,0x0,0x0,
2973 0x600000,0x0,0x18000000,0x0,0x0,0x0,0x0,0x0,0x1800,0x0,0x0,0x0,0x600060,0x30000000,0x0,0x0,0xc,0x3,0x0,0x0,0x60000c00,0x0,
2974 0x0,0xc000,0x600600,0x60000000,0x18,0xc03100,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x601f8,0x0,0x0,0x0,0x0,0x6,
2975 0x12000,0x2000000,0x40,0x20004000,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
2976 0x0,0xc06000c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x200,0x0,0x2004000,0xc00,0x0,0x0,0x0,0x0,0x0,0xc00000,
2977 0x0,0x1c000000,0x0,0x0,0x0,0x0,0x0,0xc00,0x0,0x0,0x0,0x780000,0xf0000000,0x0,0x0,0x21c,0x3,0x0,0x0,0x60000c00,0x0,0x0,0xc000,
2978 0x7c0603,0xe0000000,0x10,0xc02300,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x601f0,0x0,0x0,0x0,0x0,0x6,0x12000,0x1000000,
2979 0x40,0x7e004000,0x0,0x0,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc06000c0,0x0,
2980 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x200,0x0,0x300c000,0xc00,0x0,0x0,0x0,0x0,0x0,0xc00000,0x0,0x7800000,0x0,
2981 0x0,0x0,0x0,0x0,0x800,0x0,0x0,0x0,0x780000,0xf0000000,0x0,0x0,0x3f8,0x3e,0x0,0x0,0x60000c00,0x0,0x0,0x38000,0x3c0603,0xc0000000,
2982 0x10,0xfc00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x60000,0x0,0x0,0x0,0x0,0x6,0x0,0x1000000,0x0,0x0,0x0,0x0,
2983 0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x80600380,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
2984 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xffc,0x0,
2985 0x0,0x1f0,0x3c,0x0,0x0,0x60000c00,0x0,0x0,0x38000,0x600,0x0,0x0,0xf000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
2986 0x0,0x0,0x0,0x0,0x0,0x6,0x0,0xe000000,0x0,0x0,0x0,0x0,0x70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x70,0x0,0x0,0x0,0x0,
2987 0x0,0x0,0x0,0x3,0x80600380,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
2988 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xffc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x600,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
2989 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
2990 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 };
2993 const unsigned int font16x32[16*32*256/32] = {
2994 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
2995 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
2996 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc300000,0x0,0xc300000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
2997 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x70000e0,0x3c00730,0xe7001c0,0x0,0x70000e0,0x3c00e70,0x70000e0,0x3c00e70,0x730,0x70000e0,0x3c00730,
2998 0xe700000,0x700,0xe003c0,0xe7000e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
2999 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3000 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3001 0x0,0x0,0x6600000,0x0,0x6600000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3002 0x0,0x0,0x18001c0,0x6600ff0,0xe7003e0,0x0,0x18001c0,0x6600e70,0x18001c0,0x6600e70,0xff0,0x18001c0,0x6600ff0,0xe700000,0x180,
3003 0x1c00660,0xe7001c0,0x0,0x0,0x0,0x380,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3004 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3005 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,
3006 0x0,0x3c00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c00380,
3007 0xc300ce0,0xe700630,0x0,0x1c00380,0xc300e70,0x1c00380,0xc300e70,0xce0,0x1c00380,0xc300ce0,0xe700000,0x1c0,0x3800c30,0xe700380,
3008 0x0,0x0,0x0,0x7c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3009 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3010 0x0,0x0,0x0,0x0,0xe000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1800000,0x0,0x0,0x0,
3011 0x0,0x0,0x0,0x0,0x0,0xc300000,0x0,0xc300000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x700000,0x0,0x0,0x0,0x7c007c00,0x3e000000,
3012 0x0,0x0,0x630,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe000070,0x1800000,0xc60,0x0,0xe000070,0x1800000,0xe000070,
3013 0x1800000,0x0,0xe000070,0x1800000,0x0,0xe00,0x700180,0x70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3014 0x0,0x0,0x0,0x800000,0x0,0x600600,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3015 0x0,0x0,0x3f0,0xfc0,0x0,0x7000000,0x38000000,0x1c0000,0xfc0000,0x380001c0,0xe01c00,0x7f800000,0x0,0x0,0x0,0x0,0x0,0x0,0x7c,
3016 0x1801f00,0x0,0x0,0x1c,0x0,0x0,0x3c00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7300000,0x6600000,0x0,0x6600000,0x0,0x0,0x0,0x0,0xe700000,
3017 0x0,0x0,0x0,0x0,0x0,0xe00000,0x0,0x0,0x0,0xc000c00,0x43800000,0x0,0x0,0x630,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3018 0xf80,0x70000e0,0x3c00730,0xe700c60,0x0,0x70000e0,0x3c00e70,0x70000e0,0x3c00e70,0xe000730,0x70000e0,0x3c00730,0xe700000,0x700,
3019 0xe003c0,0xe7000e0,0x38000e70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x6300000,0x803c00,0x7c00180,
3020 0xc00300,0x1000000,0x0,0x1c,0x3c007c0,0xfc007e0,0xe01ff8,0x3f03ffc,0x7e007c0,0x0,0x0,0x7c0,0x1c0,0x7f8003f0,0x7f007ff8,0x7ff803f0,
3021 0x70381ffc,0xff0700e,0x7000783c,0x783807c0,0x7fc007c0,0x7fc00fc0,0x7fff7038,0x700ee007,0x780f780f,0x7ffc03f0,0x70000fc0,0x3c00000,
3022 0x3000000,0x38000000,0x1c0000,0x1fc0000,0x380001c0,0xe01c00,0x7f800000,0x0,0x0,0x0,0x0,0x0,0x0,0xfc,0x1801f80,0x0,0x1f80000,
3023 0x7e,0x0,0x0,0x2400000,0xfc00000,0x7ff0000,0x7ffc0000,0x0,0x0,0x0,0x0,0xf30fb0c,0x2400000,0x0,0x240780f,0x1c0,0xfc,0x780f,
3024 0x18003f0,0xe700000,0x7c00000,0x0,0xff0,0x3c00000,0x78007c0,0xc00000,0xff80000,0xf80,0x7c00000,0xc000c00,0x18001c0,0x1c001c0,
3025 0x1c001c0,0x1c003e0,0x7fe03f0,0x7ff87ff8,0x7ff87ff8,0x1ffc1ffc,0x1ffc1ffc,0x7f007838,0x7c007c0,0x7c007c0,0x7c00000,0x7c67038,
3026 0x70387038,0x7038780f,0x70001fe0,0x30000c0,0x2400f30,0xe700c60,0x0,0x30000c0,0x2400e70,0x30000c0,0x2400e70,0xf700f30,0x30000c0,
3027 0x2400f30,0xe700000,0x300,0xc00240,0xe7000c0,0x38000e70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,
3028 0x630018c,0x807e00,0xfe00180,0xc00300,0x1000000,0x0,0x38,0xff01fc0,0x3ff01ff0,0x1e01ff8,0x7f83ffc,0x1ff80ff0,0x0,0x0,0xff0,
3029 0x1f003e0,0x7fe00ff8,0x7fc07ff8,0x7ff80ff8,0x70381ffc,0xff0701c,0x7000783c,0x78381ff0,0x7fe01ff0,0x7fe01ff0,0x7fff7038,0x781ee007,
3030 0x3c1e380e,0x7ffc0380,0x380001c0,0x3c00000,0x1800000,0x38000000,0x1c0000,0x3c00000,0x380001c0,0xe01c00,0x3800000,0x0,0x0,
3031 0x0,0x7000000,0x0,0x0,0x1e0,0x18003c0,0x0,0x3fc0000,0x70,0x0,0x0,0x6600000,0x1ff00000,0x1fff0000,0x7ffc0000,0x0,0x0,0x0,0x0,
3032 0xcf0239c,0x3c00000,0x0,0x3c0380e,0x1c0,0x2001fe,0x380e,0x18007f8,0xe700000,0x8600000,0x0,0xff0,0x7e00000,0x8c00870,0x1800000,
3033 0x1ff80000,0x180,0xc600000,0xc000c00,0x38001c0,0x3e003e0,0x3e003e0,0x3e001c0,0x7fe0ff8,0x7ff87ff8,0x7ff87ff8,0x1ffc1ffc,0x1ffc1ffc,
3034 0x7fc07838,0x1ff01ff0,0x1ff01ff0,0x1ff00000,0x1fec7038,0x70387038,0x7038380e,0x70003ce0,0x1800180,0x6600cf0,0xe7007c0,0x0,
3035 0x1800180,0x6600e70,0x1800180,0x6600e70,0x7c00cf0,0x1800180,0x6600cf0,0xe700000,0x180,0x1800660,0xe700180,0x38000e70,0x0,
3036 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x630030c,0x3f0e700,0x1e200180,0x1800180,0x21100000,0x0,
3037 0x38,0x1e7819c0,0x38781038,0x1e01c00,0xf080038,0x1c381c38,0x0,0x0,0x1878,0x7fc03e0,0x70e01e18,0x70e07000,0x70001e18,0x703801c0,
3038 0x707038,0x70007c7c,0x7c381c70,0x70701c70,0x70703830,0x1c07038,0x381ce007,0x1c1c3c1e,0x3c0380,0x380001c0,0x7e00000,0xc00000,
3039 0x38000000,0x1c0000,0x3800000,0x38000000,0x1c00,0x3800000,0x0,0x0,0x0,0x7000000,0x0,0x0,0x1c0,0x18001c0,0x0,0x70c0000,0xe0,
3040 0x0,0x0,0xc300000,0x38300000,0x3c700000,0x3c0000,0x0,0x0,0x0,0x0,0xce022f4,0x1800000,0x0,0x1803c1e,0x1c0,0x2003c2,0x3c1e,
3041 0x1800e08,0x7e0,0x300000,0x0,0x7e00000,0xe700000,0x600030,0x3000000,0x3f980000,0x180,0x18200000,0xc000c00,0x1e0001c0,0x3e003e0,
3042 0x3e003e0,0x3e003e0,0xfe01e18,0x70007000,0x70007000,0x1c001c0,0x1c001c0,0x70e07c38,0x1c701c70,0x1c701c70,0x1c700000,0x3c787038,
3043 0x70387038,0x70383c1e,0x70003870,0xc00300,0xc300ce0,0x380,0x0,0xc00300,0xc300000,0xc00300,0xc300000,0xfc00ce0,0xc00300,0xc300ce0,
3044 0x0,0xc0,0x3000c30,0x300,0x38000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x630031c,0xff8c300,
3045 0x1c000180,0x1800180,0x39380000,0x0,0x70,0x1c3801c0,0x203c001c,0x3e01c00,0x1c000038,0x381c3838,0x0,0x0,0x1038,0xe0e03e0,0x70703c08,
3046 0x70707000,0x70003808,0x703801c0,0x707070,0x70007c7c,0x7c383838,0x70383838,0x70387010,0x1c07038,0x381c700e,0x1e3c1c1c,0x780380,
3047 0x1c0001c0,0xe700000,0x0,0x38000000,0x1c0000,0x3800000,0x38000000,0x1c00,0x3800000,0x0,0x0,0x0,0x7000000,0x0,0x0,0x1c0,0x18001c0,
3048 0x0,0xe000000,0xe0,0x0,0x1000100,0x3800,0x70100000,0x38700000,0x780000,0x1c0,0x7801ce0,0xe380000,0x0,0x2264,0x0,0x0,0x1c1c,
3049 0x0,0x200780,0x1c1c,0x1800c00,0x1818,0x7f00000,0x0,0x18180000,0xc300000,0x600070,0x0,0x7f980000,0x180,0x18300000,0xc000c00,
3050 0x3000000,0x3e003e0,0x3e003e0,0x3e003e0,0xee03c08,0x70007000,0x70007000,0x1c001c0,0x1c001c0,0x70707c38,0x38383838,0x38383838,
3051 0x38380000,0x38387038,0x70387038,0x70381c1c,0x7fc03870,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xbc00000,0x0,0x0,0x0,0x0,0x0,0x0,
3052 0x38000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x6300318,0xe88c300,0x1c000180,0x38001c0,
3053 0xfe00180,0x0,0x70,0x1c3801c0,0x1c001c,0x6e01c00,0x1c000078,0x381c3818,0x0,0x40000,0x40000038,0x1c0607e0,0x70703800,0x70707000,
3054 0x70003800,0x703801c0,0x7070e0,0x70007c7c,0x7c383838,0x70383838,0x70387000,0x1c07038,0x381c700e,0xf780e38,0x700380,0x1c0001c0,
3055 0x1c380000,0x0,0x38000000,0x1c0000,0x3800000,0x38000000,0x1c00,0x3800000,0x0,0x0,0x0,0x7000000,0x0,0x0,0x1c0,0x18001c0,0x0,
3056 0xe000000,0xe0,0x0,0x1000100,0x4400,0x70000000,0x38700000,0x700000,0xe0,0x7001c70,0xe380000,0x0,0x2264,0x0,0x0,0xe38,0x0,
3057 0x200700,0xe38,0x1800c00,0x300c,0xc300000,0x0,0x300c0000,0xc300180,0x6003c0,0x0,0x7f980000,0x180,0x18300000,0xc000c00,0x1800000,
3058 0x7e007e0,0x7e007e0,0x7e003e0,0xee03800,0x70007000,0x70007000,0x1c001c0,0x1c001c0,0x70707c38,0x38383838,0x38383838,0x38380000,
3059 0x38387038,0x70387038,0x70380e38,0x7ff039f0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1e00000,0x0,0x0,0x0,0x40000,0x0,0x0,0x38000000,
3060 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x6300318,0x1c80e700,0x1c000180,0x38001c0,0x3800180,
3061 0x0,0xe0,0x381c01c0,0x1c001c,0x6e01c00,0x38000070,0x381c381c,0x0,0x3c0000,0x78000078,0x38030770,0x70707800,0x70387000,0x70007000,
3062 0x703801c0,0x7071c0,0x7000745c,0x7638701c,0x7038701c,0x70387000,0x1c07038,0x1c38718e,0x7700f78,0xf00380,0xe0001c0,0x381c0000,
3063 0x7e0,0x39e003e0,0x79c03f0,0x3ffc079c,0x39e01fc0,0xfe01c1e,0x3807778,0x39e007e0,0x39e0079c,0x73c07e0,0x7ff83838,0x701ce007,
3064 0x783c701c,0x1ffc01c0,0x18001c0,0x0,0x1c000100,0xe0,0x0,0x1000100,0x4200,0x70000000,0x70700100,0xf00100,0x10000e0,0x7000c70,
3065 0xc700000,0x0,0x2204,0x7e00000,0x1e380100,0x1ffc0f78,0x0,0xf80700,0xf78,0x1800e00,0x63e6,0x18300000,0x0,0x6fe60000,0xe700180,
3066 0xc00060,0x3838,0x7f980000,0x180,0x18300000,0xc000c00,0x18001c0,0x7700770,0x7700770,0x77007f0,0xee07800,0x70007000,0x70007000,
3067 0x1c001c0,0x1c001c0,0x70387638,0x701c701c,0x701c701c,0x701c1008,0x707c7038,0x70387038,0x70380f78,0x707039c0,0x7e007e0,0x7e007e0,
3068 0x7e007e0,0x1f3c03e0,0x3f003f0,0x3f003f0,0x1fc01fc0,0x1fc01fc0,0x7f039e0,0x7e007e0,0x7e007e0,0x7e00380,0x7ce3838,0x38383838,
3069 0x3838701c,0x39e0701c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x6307fff,0x1c807e0c,0xe000180,
3070 0x30000c0,0x3800180,0x0,0xe0,0x381c01c0,0x1c001c,0xce01fe0,0x38000070,0x381c381c,0x3800380,0xfc0000,0x7e0000f0,0x30030770,
3071 0x70707000,0x70387000,0x70007000,0x703801c0,0x707380,0x700076dc,0x7638701c,0x7038701c,0x70387800,0x1c07038,0x1c3873ce,0x7f00770,
3072 0xe00380,0xe0001c0,0x700e0000,0x1ff8,0x3ff00ff0,0xffc0ff8,0x3ffc0ffc,0x3bf01fc0,0xfe01c3c,0x3807f78,0x3bf00ff0,0x3ff00ffc,
3073 0x77e0ff0,0x7ff83838,0x3838e007,0x3c783838,0x1ffc01c0,0x18001c0,0x0,0x7ff00380,0x1e0,0x0,0x1000100,0x4200,0x78000000,0x70700380,
3074 0xe00380,0x3800060,0xe000e30,0x1c600000,0x0,0x2204,0xff00000,0x7f7c0380,0x1ffc0770,0x1c0,0x3fc0700,0x18040770,0x1800780,0x4e12,
3075 0x18300104,0x0,0x4c320000,0x7e00180,0x1c00030,0x3838,0x7f980000,0x180,0x18302080,0xc000c00,0x18001c0,0x7700770,0x7700770,
3076 0x7700770,0x1ee07000,0x70007000,0x70007000,0x1c001c0,0x1c001c0,0x70387638,0x701c701c,0x701c701c,0x701c381c,0x705c7038,0x70387038,
3077 0x70380770,0x70383b80,0x1ff81ff8,0x1ff81ff8,0x1ff81ff8,0x3fbe0ff0,0xff80ff8,0xff80ff8,0x1fc01fc0,0x1fc01fc0,0xff83bf0,0xff00ff0,
3078 0xff00ff0,0xff00380,0xffc3838,0x38383838,0x38383838,0x3ff03838,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3079 0x0,0x1c0,0x7fff,0x1c803c38,0xf000000,0x70000e0,0xfe00180,0x0,0x1c0,0x381c01c0,0x3c0078,0xce01ff0,0x39e000f0,0x1c38381c,0x3800380,
3080 0x3e07ffc,0xf8001f0,0x307b0770,0x70e07000,0x70387000,0x70007000,0x703801c0,0x707700,0x700076dc,0x7638701c,0x7038701c,0x70387e00,
3081 0x1c07038,0x1c3873ce,0x3e007f0,0x1e00380,0x70001c0,0x0,0x1038,0x3c381e18,0x1c7c1e3c,0x3801e3c,0x3c7801c0,0xe01c78,0x380739c,
3082 0x3c781c38,0x3c381c3c,0x7c21e10,0x7003838,0x3838700e,0x1ef03838,0x3c01c0,0x18001c0,0x0,0x7fe007c0,0x1c0,0x0,0x1000100,0x6400,
3083 0x7e000000,0x707007c0,0x1e007c0,0x7c00070,0xe000638,0x18600000,0x0,0x0,0x1e100000,0x73ce07c0,0x3c07f0,0x1c0,0x7240700,0x1ddc3ffe,
3084 0x1800de0,0x8c01,0x1870030c,0x0,0x8c310000,0x3c00180,0x3800030,0x3838,0x7f980000,0x180,0x183030c0,0xc000c00,0x430001c0,0x7700770,
3085 0x7700770,0x7700770,0x1ce07000,0x70007000,0x70007000,0x1c001c0,0x1c001c0,0x70387638,0x701c701c,0x701c701c,0x701c1c38,0x70dc7038,
3086 0x70387038,0x703807f0,0x70383b80,0x10381038,0x10381038,0x10381038,0x21e71e18,0x1e3c1e3c,0x1e3c1e3c,0x1c001c0,0x1c001c0,0x1e383c78,
3087 0x1c381c38,0x1c381c38,0x1c380380,0x1c383838,0x38383838,0x38383838,0x3c383838,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3088 0x0,0x0,0x0,0x0,0x0,0x1c0,0x630,0x1e8000e0,0x1f000000,0x70000e0,0x39380180,0x0,0x1c0,0x3b9c01c0,0x3c07f0,0x18e01078,0x3bf800e0,
3089 0x7e0383c,0x3800380,0x1f807ffc,0x3f001c0,0x61ff0e38,0x7fc07000,0x70387ff0,0x7ff07000,0x7ff801c0,0x707f00,0x7000729c,0x7338701c,
3090 0x7070701c,0x70703fc0,0x1c07038,0x1e7873ce,0x1c003e0,0x3c00380,0x70001c0,0x0,0x1c,0x3c381c00,0x1c3c1c1c,0x3801c3c,0x383801c0,
3091 0xe01cf0,0x380739c,0x38381c38,0x3c381c3c,0x7801c00,0x7003838,0x3838700e,0xfe03c78,0x7801c0,0x18001c0,0x0,0x1c000c20,0xff8,
3092 0x0,0x1ff01ff0,0x3818,0x3fc00100,0x707e0c20,0x3c00c20,0xc200030,0xc000618,0x18c00000,0x0,0x0,0x1c000080,0xe1ce0c20,0x7803e0,
3093 0x1c0,0xe200700,0xff83ffe,0x1801878,0x9801,0x1cf0071c,0x7ffc0000,0x8c310000,0x7ffe,0x7000030,0x3838,0x3f980380,0x180,0xc6038e0,
3094 0x7f9c7f9c,0x3e1c01c0,0xe380e38,0xe380e38,0xe380f78,0x1cfc7000,0x7ff07ff0,0x7ff07ff0,0x1c001c0,0x1c001c0,0xfe387338,0x701c701c,
3095 0x701c701c,0x701c0e70,0x719c7038,0x70387038,0x703803e0,0x70383b80,0x1c001c,0x1c001c,0x1c001c,0xe71c00,0x1c1c1c1c,0x1c1c1c1c,
3096 0x1c001c0,0x1c001c0,0x1c383838,0x1c381c38,0x1c381c38,0x1c380000,0x3c383838,0x38383838,0x38383c78,0x3c383c78,0x0,0x0,0x0,0x0,
3097 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x630,0xf800380,0x3f830000,0x70000e0,0x31080180,0x0,0x380,0x3b9c01c0,
3098 0x7807e0,0x38e00038,0x3c3800e0,0xff01c3c,0x3800380,0x7c000000,0x7c03c0,0x61870e38,0x7fc07000,0x70387ff0,0x7ff070fc,0x7ff801c0,
3099 0x707f80,0x7000739c,0x7338701c,0x7ff0701c,0x7fe00ff0,0x1c07038,0xe7073ce,0x1c003e0,0x3800380,0x38001c0,0x0,0x1c,0x381c3800,
3100 0x381c380e,0x380381c,0x383801c0,0xe01de0,0x380739c,0x3838381c,0x381c381c,0x7001e00,0x7003838,0x1c70718e,0x7e01c70,0xf00380,
3101 0x18001e0,0x1e000000,0x1c001bb0,0xff8,0x0,0x1000100,0xe0,0xff00300,0x707e1bb0,0x3801bb0,0x1bb00010,0x8000308,0x30c00000,0x0,
3102 0x0,0x1e0000c0,0xe1ce1bb0,0xf003e0,0x1c0,0x1c203ff8,0x63003e0,0x180181c,0x9801,0xfb00e38,0x7ffc0000,0x8fc10000,0x7ffe,0xe000860,
3103 0x3838,0x1f980380,0x180,0x7c01c70,0x1f001f0,0x1f003c0,0xe380e38,0xe380e38,0xe380e38,0x1cfc7000,0x7ff07ff0,0x7ff07ff0,0x1c001c0,
3104 0x1c001c0,0xfe387338,0x701c701c,0x701c701c,0x701c07e0,0x731c7038,0x70387038,0x703803e0,0x70383980,0x1c001c,0x1c001c,0x1c001c,
3105 0xe73800,0x380e380e,0x380e380e,0x1c001c0,0x1c001c0,0x381c3838,0x381c381c,0x381c381c,0x381c0000,0x387c3838,0x38383838,0x38381c70,
3106 0x381c1c70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0xc30,0x7f00e00,0x33c30000,0x70000e0,0x1007ffe,
3107 0x0,0x380,0x3b9c01c0,0xf00078,0x30e0001c,0x3c1c01c0,0x1c381fdc,0x0,0x70000000,0x1c0380,0x63030e38,0x70707000,0x70387000,0x700070fc,
3108 0x703801c0,0x707b80,0x7000739c,0x7338701c,0x7fc0701c,0x7fc001f0,0x1c07038,0xe703e5c,0x3e001c0,0x7800380,0x38001c0,0x0,0x7fc,
3109 0x381c3800,0x381c380e,0x380381c,0x383801c0,0xe01fe0,0x380739c,0x3838381c,0x381c381c,0x7001fc0,0x7003838,0x1c70718e,0x7c01c70,
3110 0xe01f00,0x180007c,0x7f8c0000,0x7fc03fb8,0x1c0,0x0,0x1000100,0x700,0x1f00600,0x70703fb8,0x7803fb8,0x3fb80000,0x8000000,0x180,
3111 0x0,0x0,0x1fc00060,0xe1ce3fb8,0xe001c0,0x1c0,0x1c203ff8,0xc1801c0,0x180c,0x9801,0x1c70,0xc0000,0x8cc10000,0x180,0xfe007c0,
3112 0x3838,0x7980380,0xff0,0xe38,0x3e003e00,0x3e000380,0xe380e38,0xe380e38,0xe380e38,0x38e07000,0x70007000,0x70007000,0x1c001c0,
3113 0x1c001c0,0x70387338,0x701c701c,0x701c701c,0x701c03c0,0x731c7038,0x70387038,0x703801c0,0x703838e0,0x7fc07fc,0x7fc07fc,0x7fc07fc,
3114 0xe73800,0x380e380e,0x380e380e,0x1c001c0,0x1c001c0,0x381c3838,0x381c381c,0x381c381c,0x381c7ffc,0x38dc3838,0x38383838,0x38381c70,
3115 0x381c1c70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0xc60,0xf83878,0x71e30000,0x70000e0,0x1007ffe,
3116 0x7f0,0x380,0x381c01c0,0x1e0003c,0x60e0001c,0x381c01c0,0x381c079c,0x0,0x7c000000,0x7c0380,0x63031c1c,0x70307000,0x70387000,
3117 0x7000701c,0x703801c0,0x7071c0,0x7000739c,0x71b8701c,0x7000701c,0x71e00078,0x1c07038,0xe703e7c,0x7e001c0,0xf000380,0x38001c0,
3118 0x0,0x1ffc,0x381c3800,0x381c3ffe,0x380381c,0x383801c0,0xe01fc0,0x380739c,0x3838381c,0x381c381c,0x7000ff0,0x7003838,0x1ef03bdc,
3119 0x3800ee0,0x1e01f00,0x180007c,0x61fc0000,0x7fc07f3c,0x1c0,0x0,0x1000100,0x1800,0x780c00,0x70707f3c,0xf007f3c,0x7f3c0000,0x0,
3120 0x3c0,0x3ffcffff,0x0,0xff00030,0xe1fe7f3c,0x1e001c0,0x1c0,0x1c200700,0xc183ffe,0xe0c,0x9801,0x1ff038e0,0xc07f0,0x8c610000,
3121 0x180,0x0,0x3838,0x1980380,0x0,0x1ff0071c,0xe000e000,0xe0000f80,0x1c1c1c1c,0x1c1c1c1c,0x1c1c1e38,0x38e07000,0x70007000,0x70007000,
3122 0x1c001c0,0x1c001c0,0x703871b8,0x701c701c,0x701c701c,0x701c03c0,0x761c7038,0x70387038,0x703801c0,0x70703870,0x1ffc1ffc,0x1ffc1ffc,
3123 0x1ffc1ffc,0xfff3800,0x3ffe3ffe,0x3ffe3ffe,0x1c001c0,0x1c001c0,0x381c3838,0x381c381c,0x381c381c,0x381c7ffc,0x389c3838,0x38383838,
3124 0x38380ee0,0x381c0ee0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0xfffc,0xbc60fc,0x70e30000,0x70000e0,
3125 0x180,0x7f0,0x700,0x381c01c0,0x3e0001c,0x7ffc001c,0x381c03c0,0x381c001c,0x0,0x1f807ffc,0x3f00380,0x63031ffc,0x70387000,0x70387000,
3126 0x7000701c,0x703801c0,0x7071e0,0x7000701c,0x71b8701c,0x7000701c,0x70f00038,0x1c07038,0x7e03e7c,0x77001c0,0xe000380,0x1c001c0,
3127 0x0,0x3c1c,0x381c3800,0x381c3ffe,0x380381c,0x383801c0,0xe01fe0,0x380739c,0x3838381c,0x381c381c,0x70003f8,0x7003838,0xee03bdc,
3128 0x3c00ee0,0x3c00380,0x18000e0,0xf00000,0x1c007e7c,0x3c0,0x0,0x1000100,0x0,0x381800,0x70707e7c,0xe007e7c,0x7e7c0000,0x0,0x7c0,
3129 0x0,0x0,0x3f80018,0xe1fe7e7c,0x3c001c0,0x1c0,0x1c200700,0xc183ffe,0xf0c,0x8c01,0x38e0,0xc07f0,0x8c710000,0x180,0x0,0x3838,
3130 0x1980000,0x0,0x71c,0x7000f0,0x700f00,0x1ffc1ffc,0x1ffc1ffc,0x1ffc1ffc,0x3fe07000,0x70007000,0x70007000,0x1c001c0,0x1c001c0,
3131 0x703871b8,0x701c701c,0x701c701c,0x701c07e0,0x7c1c7038,0x70387038,0x703801c0,0x7ff03838,0x3c1c3c1c,0x3c1c3c1c,0x3c1c3c1c,
3132 0x3fff3800,0x3ffe3ffe,0x3ffe3ffe,0x1c001c0,0x1c001c0,0x381c3838,0x381c381c,0x381c381c,0x381c0000,0x391c3838,0x38383838,0x38380ee0,
3133 0x381c0ee0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfffc,0x9c01ce,0x70f60000,0x70000e0,0x180,
3134 0x0,0x700,0x381c01c0,0x780001c,0x7ffc001c,0x381c0380,0x381c003c,0x0,0x3e07ffc,0xf800380,0x63031ffc,0x70387000,0x70387000,
3135 0x7000701c,0x703801c0,0x7070f0,0x7000701c,0x71b8701c,0x7000701c,0x70700038,0x1c07038,0x7e03e7c,0xf7801c0,0x1e000380,0x1c001c0,
3136 0x0,0x381c,0x381c3800,0x381c3800,0x380381c,0x383801c0,0xe01fe0,0x380739c,0x3838381c,0x381c381c,0x7000078,0x7003838,0xee03a5c,
3137 0x7c00fe0,0x78001c0,0x18001c0,0x0,0x1c003ef8,0x380,0x0,0x1000100,0x810,0x383000,0x70703ef8,0x1e003ef8,0x3ef80000,0x0,0x7c0,
3138 0x0,0x0,0x78000c,0xe1c03ef8,0x78001c0,0x1c0,0x1c200700,0x63001c0,0x18003f8,0x4e12,0x1c70,0xc0000,0x4c320000,0x180,0x0,0x3838,
3139 0x1980000,0x0,0xe38,0x700118,0x701e00,0x1ffc1ffc,0x1ffc1ffc,0x1ffc1ffc,0x7fe07000,0x70007000,0x70007000,0x1c001c0,0x1c001c0,
3140 0x703871b8,0x701c701c,0x701c701c,0x701c0e70,0x7c1c7038,0x70387038,0x703801c0,0x7fc0381c,0x381c381c,0x381c381c,0x381c381c,
3141 0x78e03800,0x38003800,0x38003800,0x1c001c0,0x1c001c0,0x381c3838,0x381c381c,0x381c381c,0x381c0000,0x3b1c3838,0x38383838,0x38380fe0,
3142 0x381c0fe0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1860,0x9c0186,0x707e0000,0x30000c0,0x180,
3143 0x0,0xe00,0x183801c0,0xf00001c,0xe0001c,0x181c0380,0x381c0038,0x0,0xfc0000,0x7e000000,0x61873c1e,0x70383800,0x70707000,0x7000381c,
3144 0x703801c0,0x707070,0x7000701c,0x70f83838,0x70003838,0x70780038,0x1c07038,0x7e03c3c,0xe3801c0,0x1c000380,0xe001c0,0x0,0x381c,
3145 0x381c3800,0x381c3800,0x380381c,0x383801c0,0xe01ef0,0x380739c,0x3838381c,0x381c381c,0x7000038,0x7003838,0xfe03e7c,0xfe007c0,
3146 0x70001c0,0x18001c0,0x0,0xe001ff0,0x380,0x0,0x1000100,0x162c,0x381800,0x30701ff0,0x1c001ff0,0x1ff00000,0x0,0x3c0,0x0,0x0,
3147 0x380018,0xe1c01ff0,0x70001c0,0x1c0,0x1c200700,0xff801c0,0x18000f0,0x63e6,0xe38,0x0,0x6c3e0000,0x0,0x0,0x3838,0x1980000,0x0,
3148 0x1c70,0xf0000c,0xf01c00,0x3c1e3c1e,0x3c1e3c1e,0x3c1e3c1c,0x70e03800,0x70007000,0x70007000,0x1c001c0,0x1c001c0,0x707070f8,
3149 0x38383838,0x38383838,0x38381c38,0x38387038,0x70387038,0x703801c0,0x7000381c,0x381c381c,0x381c381c,0x381c381c,0x70e03800,
3150 0x38003800,0x38003800,0x1c001c0,0x1c001c0,0x381c3838,0x381c381c,0x381c381c,0x381c0380,0x3e1c3838,0x38383838,0x383807c0,0x381c07c0,
3151 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x18c0,0x9c0186,0x783c0000,0x38001c0,0x180,0x3800000,
3152 0x3800e00,0x1c3801c0,0x1e00003c,0xe00038,0x1c1c0780,0x381c0038,0x3800380,0x3c0000,0x78000000,0x61ff380e,0x70383808,0x70707000,
3153 0x7000381c,0x703801c0,0x40707078,0x7000701c,0x70f83838,0x70003838,0x70384038,0x1c07038,0x7e03c3c,0x1e3c01c0,0x3c000380,0xe001c0,
3154 0x0,0x383c,0x3c381c00,0x1c3c1c00,0x3801c3c,0x383801c0,0xe01c78,0x380739c,0x38381c38,0x3c381c3c,0x7000038,0x7003878,0x7c01e78,
3155 0x1ef007c0,0xf0001c0,0x18001c0,0x0,0xe000ee0,0x7800380,0xe380000,0x1001ff0,0x2242,0x40380c00,0x38700ee0,0x3c000ee0,0xee00000,
3156 0x0,0x0,0x0,0x0,0x380030,0xe1c00ee0,0xf0001c0,0x1c0,0xe200700,0xdd801c0,0x1800038,0x300c,0x71c,0x0,0x300c0000,0x0,0x0,0x3838,
3157 0x1980000,0x0,0x38e0,0xb0000c,0xb01c08,0x380e380e,0x380e380e,0x380e380e,0x70e03808,0x70007000,0x70007000,0x1c001c0,0x1c001c0,
3158 0x707070f8,0x38383838,0x38383838,0x3838381c,0x38387038,0x70387038,0x703801c0,0x7000381c,0x383c383c,0x383c383c,0x383c383c,
3159 0x70e01c00,0x1c001c00,0x1c001c00,0x1c001c0,0x1c001c0,0x1c383838,0x1c381c38,0x1c381c38,0x1c380380,0x1c383878,0x38783878,0x387807c0,
3160 0x3c3807c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x18c0,0x10b801ce,0x3c3e0000,0x38001c0,0x180,
3161 0x3800000,0x3801c00,0x1e7801c0,0x3c002078,0xe02078,0x1c380700,0x1c3810f0,0x3800380,0x40000,0x40000380,0x307b380e,0x70701e18,
3162 0x70e07000,0x70001c1c,0x703801c0,0x60e0703c,0x7000701c,0x70f83c78,0x70003c70,0x703c70f0,0x1c03870,0x3c01c3c,0x3c1c01c0,0x78000380,
3163 0x7001c0,0x0,0x3c7c,0x3c381e18,0x1c7c1e0c,0x3801c3c,0x383801c0,0xe01c38,0x3c0739c,0x38381c38,0x3c381c3c,0x7001078,0x7803c78,
3164 0x7c01c38,0x1c780380,0x1e0001c0,0x18001c0,0x0,0x70c06c0,0x7000380,0xe300000,0x1000100,0x2142,0x70f00600,0x3c7006c0,0x780006c0,
3165 0x6c00000,0x0,0x0,0x0,0x0,0x10780060,0x73e206c0,0x1e0001c0,0x1c0,0x7240700,0x180c01c0,0x1800018,0x1818,0x30c,0x0,0x18180000,
3166 0x0,0x0,0x3c78,0x1980000,0x0,0x30c0,0x130000c,0x1301c18,0x380e380e,0x380e380e,0x380e380e,0x70e01e18,0x70007000,0x70007000,
3167 0x1c001c0,0x1c001c0,0x70e070f8,0x3c783c78,0x3c783c78,0x3c781008,0x7c783870,0x38703870,0x387001c0,0x70003a3c,0x3c7c3c7c,0x3c7c3c7c,
3168 0x3c7c3c7c,0x79f11e18,0x1e0c1e0c,0x1e0c1e0c,0x1c001c0,0x1c001c0,0x1c783838,0x1c381c38,0x1c381c38,0x1c380380,0x1c383c78,0x3c783c78,
3169 0x3c780380,0x3c380380,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x38c0,0x1ff800fc,0x1fee0000,
3170 0x1800180,0x180,0x3800000,0x3801c00,0xff01ffc,0x3ffc3ff0,0xe03ff0,0xff00700,0x1ff81fe0,0x3800380,0x0,0x380,0x3000780f,0x7ff00ff8,
3171 0x7fc07ff8,0x70000ffc,0x70381ffc,0x7fe0701c,0x7ff8701c,0x70781ff0,0x70001ff0,0x701c7ff0,0x1c01fe0,0x3c01c38,0x380e01c0,0x7ffc0380,
3172 0x7001c0,0x0,0x1fdc,0x3ff00ff0,0xffc0ffc,0x3800fdc,0x38383ffe,0xe01c3c,0x1fc739c,0x38380ff0,0x3ff00ffc,0x7001ff0,0x3f81fb8,
3173 0x7c01c38,0x3c3c0380,0x1ffc01c0,0x18001c0,0x0,0x3fc0380,0x7000380,0xc70718c,0x1000100,0x2244,0x7ff00200,0x1fff0380,0x7ffc0380,
3174 0x3800000,0x0,0x0,0x0,0x0,0x1ff000c0,0x7f7e0380,0x1ffc01c0,0x1c0,0x3fc3ffe,0x1c0,0x1800018,0x7e0,0x104,0x0,0x7e00000,0x7ffe,
3175 0x0,0x3fde,0x1980000,0x0,0x2080,0x3300018,0x3300ff0,0x780f780f,0x780f780f,0x780f780e,0xf0fe0ff8,0x7ff87ff8,0x7ff87ff8,0x1ffc1ffc,
3176 0x1ffc1ffc,0x7fc07078,0x1ff01ff0,0x1ff01ff0,0x1ff00000,0x7ff01fe0,0x1fe01fe0,0x1fe001c0,0x70003bf8,0x1fdc1fdc,0x1fdc1fdc,
3177 0x1fdc1fdc,0x3fbf0ff0,0xffc0ffc,0xffc0ffc,0x3ffe3ffe,0x3ffe3ffe,0xff03838,0xff00ff0,0xff00ff0,0xff00000,0x3ff01fb8,0x1fb81fb8,
3178 0x1fb80380,0x3ff00380,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1c0,0x31c0,0x7e00078,0x7cf0000,0x1800180,
3179 0x0,0x3800000,0x3803800,0x3c01ffc,0x3ffc0fe0,0xe01fc0,0x3e00e00,0x7e00f80,0x3800380,0x0,0x380,0x18007007,0x7fc003f0,0x7f007ff8,
3180 0x700003f0,0x70381ffc,0x3f80701e,0x7ff8701c,0x707807c0,0x700007c0,0x701e1fc0,0x1c00fc0,0x3c01818,0x780f01c0,0x7ffc0380,0x3801c0,
3181 0x0,0xf9c,0x39e003e0,0x79c03f0,0x380079c,0x38383ffe,0xe01c1e,0x7c739c,0x383807e0,0x39e0079c,0x7000fc0,0x1f80f38,0x3801c38,
3182 0x781e0380,0x1ffc01c0,0x18001c0,0x0,0x1f80100,0xe000700,0x1c60718c,0x1000100,0x1e3c,0x1fc00100,0x7ff0100,0x7ffc0100,0x1000000,
3183 0x0,0x0,0x0,0x0,0xfc00080,0x3e3c0100,0x1ffc01c0,0x1c0,0xf83ffe,0x1c0,0x1800838,0x0,0x0,0x0,0x0,0x7ffe,0x0,0x3b9e,0x1980000,
3184 0x0,0x0,0x2300038,0x23003e0,0x70077007,0x70077007,0x70077007,0xe0fe03f0,0x7ff87ff8,0x7ff87ff8,0x1ffc1ffc,0x1ffc1ffc,0x7f007078,
3185 0x7c007c0,0x7c007c0,0x7c00000,0xc7c00fc0,0xfc00fc0,0xfc001c0,0x700039f0,0xf9c0f9c,0xf9c0f9c,0xf9c0f9c,0x1f1e03e0,0x3f003f0,
3186 0x3f003f0,0x3ffe3ffe,0x3ffe3ffe,0x7e03838,0x7e007e0,0x7e007e0,0x7e00000,0x63e00f38,0xf380f38,0xf380380,0x39e00380,0x0,0x0,
3187 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x800000,0x0,0xc00300,0x0,0x3000000,0x3800,0x0,0x0,0x0,0x0,
3188 0x0,0x300,0x0,0x0,0x1c000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe0,0x0,0x0,0x0,0x0,0x380,0x3801c0,0x0,0x0,0x0,0x0,0x1c,0x0,0xe00000,
3189 0x0,0x0,0x3800001c,0x0,0x0,0x0,0x700,0x1c0,0x18001c0,0x0,0x0,0xe000700,0x18600000,0x1000100,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3190 0x0,0x0,0x0,0x0,0x0,0x200000,0x0,0x1800ff0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x1980000,0x1800000,0x0,0x6300070,0x6300000,0x0,
3191 0x0,0x0,0xc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40000000,
3192 0x0,0x700,0x38000700,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x800000,0x0,0xc00300,0x0,0x7000000,
3193 0x7000,0x0,0x0,0x0,0x0,0x0,0x700,0x0,0x0,0xf040000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x78,0x0,0x0,0x0,0x0,0x3f0,0x1c0fc0,0x0,0x0,
3194 0x0,0x0,0x1c,0x0,0xe00000,0x0,0x0,0x3800001c,0x0,0x0,0x0,0x700,0x1e0,0x18003c0,0x0,0x0,0xc000700,0x18c00000,0x1000000,0x0,
3195 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x200000,0x0,0x18007e0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x1980000,0xc00000,
3196 0x0,0x7f800e0,0x7f80000,0x0,0x0,0x0,0x60,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x60,0x0,0x0,0x0,0x0,
3197 0x0,0x0,0x0,0x0,0x0,0x0,0x700,0x38000700,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x800000,
3198 0x0,0x600600,0x0,0x6000000,0x0,0x0,0x0,0x0,0x0,0x0,0x600,0x0,0x0,0x7fc0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30,0x0,0x0,0x0,0x0,
3199 0x3f0,0xfc0,0x0,0x0,0x0,0x0,0x838,0x0,0x1e00000,0x0,0x0,0x3800001c,0x0,0x0,0x0,0xf00,0xfc,0x1801f80,0x0,0x0,0x8008e00,0x30c00000,
3200 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x200000,0x0,0x1800000,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x1980000,0xc00000,
3201 0x0,0x3001c0,0x300000,0x0,0x0,0x0,0x60,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x60,0x0,0x0,0x0,0x0,0x0,
3202 0x0,0x0,0x0,0x0,0x0,0xf00,0x38000f00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x800000,0x0,
3203 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfc0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3204 0x0,0x0,0xff0,0x0,0x1fc00000,0x0,0x0,0x3800001c,0x0,0x0,0x0,0x3e00,0x7c,0x1801f00,0x0,0x0,0x800fe00,0x0,0x0,0x0,0x0,0x0,0x0,
3205 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x200000,0x0,0x1800000,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x0,0x7c00000,0x0,0x3001fc,0x300000,
3206 0x0,0x0,0x0,0x3e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3207 0x3e00,0x38003e00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3208 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfff8,0x0,0x0,0x0,0x7e0,0x0,0x1f000000,
3209 0x0,0x0,0x3800001c,0x0,0x0,0x0,0x3c00,0x0,0x1800000,0x0,0x0,0x7800,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3210 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3800,0x0,0x7800000,0x0,0x0,0x0,0x0,0x0,0x0,0x3c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3211 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00,0x38003c00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3212 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3213 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfff8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1800000,0x0,0x0,0x0,0x0,
3214 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3215 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3216 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3217 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3218 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3219 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3220 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3221 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3222 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3223 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3224 0x0,0x0,0x0,0x0,0x0,0x0,0x0 };
3227 const unsigned int font29x57[29*57*256/32] = {
3228 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3229 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3230 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3231 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3232 0x0,0x781e00,0x0,0x0,0x7,0x81e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3233 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7c0000,0xf8000,0x7e00000,0x0,0x7,
3234 0xc0000000,0x0,0x7c00,0xf80,0x7e000,0x0,0x7c00000,0xf80000,0x7e000000,0x0,0x0,0x1f00,0x3e0,0x1f800,0x0,0x0,0x0,0x3,0xe0000000,
3235 0x7c00003f,0x0,0xf8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3236 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3237 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3238 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3239 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3240 0x0,0x0,0x0,0x0,0x0,0x0,0x3c3c00,0x0,0x0,0x3,0xc3c00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3e1f00,
3241 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3e0000,
3242 0x1f0000,0x7e00000,0xf838001f,0xf80001f,0xf0000000,0x0,0x3e00,0x1f00,0x7e000,0x3e1f000,0x3e00000,0x1f00000,0x7e00003e,0x1f000000,
3243 0x3e0,0xe0000f80,0x7c0,0x1f800,0x3e0e00,0x7c3e000,0x0,0x1,0xf0000000,0xf800003f,0x1f0f,0x800001f0,0x0,0x0,0x0,0x0,0x0,0x0,
3244 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3245 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3246 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3247 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3248 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1e7800,0x0,0x0,
3249 0x1,0xe7800000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3e1f00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3250 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1e0000,0x1e0000,0xff00001,0xfe38001f,0xf80003f,
3251 0xf8000000,0x0,0x1e00,0x1e00,0xff000,0x3e1f000,0x1e00000,0x1e00000,0xff00003e,0x1f000000,0x7f8,0xe0000780,0x780,0x3fc00,0x7f8e00,
3252 0x7c3e000,0x0,0x0,0xf0000000,0xf000007f,0x80001f0f,0x800001e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3253 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3254 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3255 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3256 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3257 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xef000,0x0,0x0,0x0,0xef000000,0x0,0x0,0x0,0x0,0x0,0x0,
3258 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3e1f00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3259 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0000,0x3c0000,0x1e780003,0xfff8001f,0xf80003c,0x78000000,0x0,0xf00,0x3c00,0x1e7800,
3260 0x3e1f000,0xf00000,0x3c00001,0xe780003e,0x1f000000,0xfff,0xe00003c0,0xf00,0x79e00,0xfffe00,0x7c3e000,0x0,0x0,0x78000001,0xe00000f3,
3261 0xc0001f0f,0x800003c0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3262 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3263 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3264 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3265 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3266 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7e000,0x0,0x0,0x0,0x7e000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3267 0x3e1f00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3268 0x0,0x78000,0x780000,0x3c3c0003,0x8ff0001f,0xf800078,0x3c000000,0x0,0x780,0x7800,0x3c3c00,0x3e1f000,0x780000,0x7800003,0xc3c0003e,
3269 0x1f000000,0xe3f,0xc00001e0,0x1e00,0xf0f00,0xe3fc00,0x7c3e000,0x0,0x0,0x3c000003,0xc00001e1,0xe0001f0f,0x80000780,0x0,0x0,
3270 0x0,0x0,0x0,0x0,0x1f,0xf0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3271 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3272 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3273 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3274 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3275 0x0,0x7e000,0x0,0x0,0x0,0x7e000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3e1f00,0x0,0x0,0x0,0x0,0x0,0x0,
3276 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfc00,0x7e000,0xfe000,0x0,0x3c000,0xf00000,0x781e0003,
3277 0x83e0001f,0xf800070,0x1c000000,0x0,0x3c0,0xf000,0x781e00,0x3e1f000,0x3c0000,0xf000007,0x81e0003e,0x1f000000,0xe0f,0x800000f0,
3278 0x3c00,0x1e0780,0xe0f800,0x7c3e000,0x0,0x0,0x1e000007,0x800003c0,0xf0001f0f,0x80000f00,0x0,0x0,0x0,0x0,0x0,0x0,0x3f,0xf8000000,
3279 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3280 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3281 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3282 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3283 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3284 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3285 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3fc00,0x1fe000,0x3ff800,0x0,0x0,0x0,0x0,0x0,0x70,0x1c000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3286 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c,0x78000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3287 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3288 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3289 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3290 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1f00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3291 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3292 0x0,0x0,0x78,0xf000000,0x0,0x0,0x780f0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7c0,
3293 0x0,0x0,0x0,0x0,0x0,0x0,0x3fc00,0x1fe000,0x3ffc00,0x0,0x0,0x0,0x0,0x0,0x70,0x1c000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3294 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1f00000,0x3e000,0x3e00000,0x0,0x78,0x3c000000,0x0,0x1f000,0x3e0,
3295 0x3e000,0x0,0x1f000000,0x3e0000,0x3e000000,0x0,0x0,0x7c00,0xf8,0xf800,0x0,0x0,0x0,0xf,0x80000000,0x1f00001f,0x0,0x3e,0x0,
3296 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3297 0x0,0x0,0x0,0x30000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3298 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf80000,
3299 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3300 0x0,0x0,0x0,0x0,0xf80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x781c0000,0x38,0xe000000,0x0,0x0,0x380e0,0x0,
3301 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf80,0x0,0x0,0x0,0x0,0x0,0x0,0x39c00,0x1ce000,0x303e00,
3302 0x0,0x0,0x0,0x0,0x0,0x78,0x3c000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4000,0x0,0x0,0x0,0x0,
3303 0x0,0x0,0xf80000,0x7c000,0x3e00000,0xf0380000,0x70,0x1c000000,0x0,0xf800,0x7c0,0x3e000,0x0,0xf800000,0x7c0000,0x3e000000,
3304 0x0,0x3c0,0xe0003e00,0x1f0,0xf800,0x3c0e00,0x0,0x0,0x7,0xc0000000,0x3e00001f,0x0,0x7c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3305 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30000000,0xff,0x0,
3306 0xf8,0xf8000,0x1c000,0x0,0x0,0x0,0x0,0x1f,0xc0000000,0x1ff8,0xff00,0x0,0x0,0x3fe000,0x0,0x1fc00001,0xfe000000,0x0,0x0,0x0,
3307 0x0,0x7f800,0x0,0x0,0x0,0xff00000,0x0,0x0,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0xf8000000,0xfe,0x0,0x7f80,0x0,0x0,0x0,0x0,0x0,
3308 0x0,0x3f,0xf0000000,0x7fe0,0x0,0x0,0x780000,0x1,0xe0000000,0x0,0x780000,0x3,0xfe000000,0x78000,0x3c00,0xf000,0x7800003,0xffe00000,
3309 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfc0000f0,0x3f000,0x0,0x0,0x3fc00,0x0,0x0,0x1fc000,0x0,0x0,0x0,0x1fc0,
3310 0x0,0xff000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfe1c0000,0x1c,0x1c000000,0x0,0x0,0x1c1c0,0x0,0x0,0x0,0x0,0x1fe0000,
3311 0x0,0x0,0x1ff,0x1f0f8,0x0,0xff000,0x0,0x0,0x0,0x3f,0xff00000f,0x80000000,0xfe0,0x3f80,0xf00,0x0,0x0,0x0,0x1,0xf8000003,0xe0000000,
3312 0x1c00,0xe000,0xe00,0x0,0x0,0x0,0x0,0x0,0x3c,0x78000000,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7f0,0x3f80,0x1fc00,0xfe000,
3313 0x7f0000,0x0,0x1fc07000,0x0,0x0,0x0,0x0,0x0,0x3f800,0x780000,0x78000,0x7f00001,0xfc38001f,0xf800070,0x1c000000,0x0,0x7800,
3314 0x780,0x7f000,0x3e1f000,0x7800000,0x780000,0x7f00003e,0x1f0003f0,0x7f0,0xe0001e00,0x1e0,0x1fc00,0x7f0e00,0x7c3e000,0x0,0x3,
3315 0xc0000000,0x3c00003f,0x80001f0f,0x80000078,0x1e0000,0x3e1f00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3316 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x3c1e0000,0x1e078000,0x30000000,0x3ff,0xc00001e0,0xf0,
3317 0x78000,0x1c000,0x0,0x0,0x0,0x0,0x1e0007f,0xf000007e,0x1ffff,0x7ffe0,0x1f80,0x3ffff80,0xfff803,0xfffff800,0xfff80007,0xff800000,
3318 0x0,0x0,0x0,0x0,0x1ffe00,0x0,0xfe0003,0xfff80000,0x3ffe01ff,0xe00003ff,0xffe01fff,0xff0003ff,0xe01e0007,0x803ffff0,0xfff80,
3319 0x3c000fc0,0x7800001f,0x8003f07e,0x1e000f,0xfe0007ff,0xf00003ff,0x8007ffe0,0x1fff8,0x7fffffe,0xf0003c1,0xe000079e,0xf1f,0x1f3e0,
3320 0x1f01ff,0xfff8003f,0xf003c000,0x7fe0,0x3f00,0x0,0x3c0000,0x1,0xe0000000,0x0,0x780000,0xf,0xfe000000,0x78000,0x3c00,0xf000,
3321 0x7800003,0xffe00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0xfc0000f0,0x3fe00,0x0,0x0,0xfff00,0x0,0x0,0x3fe000,
3322 0x0,0x0,0x0,0x1dc0,0x0,0x3fff00,0x0,0x3ffff80,0x1f,0xffff8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff1c07ff,0x3c0f001e,0x3c000000,
3323 0x0,0x0,0x1e3c0,0xf80007c,0x0,0x780000,0x0,0xfff8000,0x3e00,0x1f00000,0x7ff,0xc001f0f8,0x0,0x3ffc00,0x0,0x0,0x0,0x3f,0xff00003f,
3324 0xe0000000,0x3ff8,0xffe0,0x1e00,0x0,0xfffc00,0x0,0x7,0xf800000f,0xf8000000,0x1c00,0xe000,0xe00,0xf000,0x1fc000,0xfe0000,0x7f00000,
3325 0x3f800001,0xfc00003f,0xf80000ff,0xffc003ff,0xe007ffff,0xc03ffffe,0x1fffff0,0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01ffc,
3326 0xfc00,0x3c001ffc,0xffe0,0x7ff00,0x3ff800,0x1ffc000,0x0,0x7ff8f0f0,0x3c0780,0x1e03c00,0xf01e000,0x783e0001,0xf01e0000,0xffe00,
3327 0x3c0000,0xf0000,0x7700001,0xfe38001f,0xf800070,0x1c000000,0x0,0x3c00,0xf00,0x77000,0x3e1f000,0x3c00000,0xf00000,0x7700003e,
3328 0x1f0000f8,0xc0007f8,0xe0000f00,0x3c0,0x1dc00,0x7f8e00,0x7c3e000,0x0,0x1,0xe0000000,0x7800003b,0x80001f0f,0x800000f0,0x1e0000,
3329 0x3e1f00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3330 0x0,0x0,0x780000,0x3c1e0000,0x1e070000,0x300001f0,0x7ff,0xc00001e0,0x1e0,0x7c000,0x1c000,0x0,0x0,0x0,0x0,0x3c000ff,0xf80007fe,
3331 0x3ffff,0x801ffff8,0x1f80,0x3ffff80,0x3fff803,0xfffff801,0xfffc000f,0xffc00000,0x0,0x0,0x0,0x0,0x7fff80,0x0,0xfe0003,0xffff0000,
3332 0xffff01ff,0xfc0003ff,0xffe01fff,0xff000fff,0xf01e0007,0x803ffff0,0xfff80,0x3c001f80,0x7800001f,0xc007f07e,0x1e001f,0xff0007ff,
3333 0xfc0007ff,0xc007fffc,0x3fffc,0x7fffffe,0xf0003c1,0xf0000f9e,0xf0f,0x8003e1e0,0x1e01ff,0xfff8003f,0xf001e000,0x7fe0,0x3f00,
3334 0x0,0x1e0000,0x1,0xe0000000,0x0,0x780000,0x1f,0xfe000000,0x78000,0x3c00,0xf000,0x7800003,0xffe00000,0x0,0x0,0x0,0x0,0x0,0x0,
3335 0x0,0x0,0x0,0x0,0x0,0x0,0xf,0xfc0000f0,0x3ff00,0x0,0x0,0x1fff80,0x0,0x0,0xffe000,0x0,0x0,0x0,0x3de0,0x0,0x7fff80,0x0,0xfffff80,
3336 0x1f,0xffff8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xe7bc07ff,0x3e1f000f,0x78000000,0x0,0x0,0xf780,0x7800078,0x0,0x780000,0x180000,
3337 0x1fff8000,0x1e00,0x1e0003c,0xfff,0xc001f0f8,0x0,0x7ffe00,0x0,0x0,0x0,0x3f,0xff00007f,0xf0000000,0x3ffc,0xfff0,0x3c00,0x0,
3338 0x7fffc00,0x0,0x7,0xf800003f,0xfe000000,0x1c00,0xe000,0xe00,0xf000,0x1fc000,0xfe0000,0x7f00000,0x3f800001,0xfc00001f,0xe00001ff,
3339 0xffc00fff,0xf007ffff,0xc03ffffe,0x1fffff0,0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01fff,0xc000fc00,0x3c003ffe,0x1fff0,
3340 0xfff80,0x7ffc00,0x3ffe000,0x0,0xfffce0f0,0x3c0780,0x1e03c00,0xf01e000,0x781e0001,0xe01e0000,0x3fff00,0x1e0000,0x1e0000,0xf780003,
3341 0xcf78001f,0xf800078,0x3c000000,0x0,0x1e00,0x1e00,0xf7800,0x3e1f000,0x1e00000,0x1e00000,0xf780003e,0x1f0000fc,0x7c000f3d,
3342 0xe0000780,0x780,0x3de00,0xf3de00,0x7c3e000,0x0,0x0,0xf0000000,0xf000007b,0xc0001f0f,0x800001e0,0x1e0000,0x3e1f00,0x0,0x0,
3343 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,
3344 0x3c1e0000,0x1e0f0000,0x300007fc,0xfff,0xc00001e0,0x1e0,0x3c000,0x1c000,0x0,0x0,0x0,0x0,0x3c001ff,0xfc001ffe,0x3ffff,0xc01ffffc,
3345 0x3f80,0x3ffff80,0x7fff803,0xfffff803,0xfffe001f,0xffe00000,0x0,0x0,0x0,0x0,0xffff80,0x7f800,0xfe0003,0xffff8001,0xffff01ff,
3346 0xff0003ff,0xffe01fff,0xff001fff,0xf01e0007,0x803ffff0,0xfff80,0x3c003f00,0x7800001f,0xc007f07f,0x1e003f,0xff8007ff,0xff000fff,
3347 0xe007ffff,0x7fffc,0x7fffffe,0xf0003c0,0xf0000f1e,0xf07,0x8003c1f0,0x3e01ff,0xfff8003f,0xf001e000,0x7fe0,0x7f80,0x0,0xe0000,
3348 0x1,0xe0000000,0x0,0x780000,0x1f,0xfe000000,0x78000,0x3c00,0xf000,0x7800003,0xffe00000,0x0,0x0,0x0,0x0,0x0,0x0,0x3c000,0x0,
3349 0x0,0x0,0x0,0x0,0xf,0xfc0000f0,0x3ff00,0x0,0x0,0x3fff80,0x0,0x0,0xffe000,0x0,0x0,0x0,0x78f0,0x0,0xffff80,0x0,0x3fffff80,0x1f,
3350 0xffff8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xc7f80070,0x3e1f0007,0x70000000,0x0,0x0,0x7700,0x7c000f8,0x0,0x780000,0x180000,
3351 0x3fff8000,0x1f00,0x3e0003c,0x1f03,0xc001f0f8,0x0,0x703f00,0x0,0x0,0x0,0x3f,0xff0000f0,0xf8000000,0x303e,0xc0f8,0x7800,0x0,
3352 0xffffc00,0x0,0x7,0x3800003e,0x3e000000,0x1c00,0xe000,0x3c00,0xf000,0x1fc000,0xfe0000,0x7f00000,0x3f800001,0xfc00000f,0xe00001ff,
3353 0xffc01fff,0xf007ffff,0xc03ffffe,0x1fffff0,0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01fff,0xf000fe00,0x3c007fff,0x3fff8,
3354 0x1fffc0,0xfffe00,0x7fff000,0x1,0xffffc0f0,0x3c0780,0x1e03c00,0xf01e000,0x781f0003,0xe01e0000,0x3fff80,0xe0000,0x3c0000,0x1e3c0003,
3355 0x8ff0001f,0xf80003c,0x78000000,0x0,0xe00,0x3c00,0x1e3c00,0x3e1f000,0xe00000,0x3c00001,0xe3c0003e,0x1f00007f,0xf8000e3f,0xc0000380,
3356 0xf00,0x78f00,0xe3fc00,0x7c3e000,0x0,0x0,0x70000001,0xe00000f1,0xe0001f0f,0x800003c0,0x1e0000,0x3e1f00,0x0,0x0,0x0,0x0,0x0,
3357 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x3c1e0000,0x3c0f0000,
3358 0x30000ffe,0xf80,0xc00001e0,0x3c0,0x1e000,0x101c040,0x0,0x0,0x0,0x0,0x78003f0,0x7e001ffe,0x3f807,0xe01f00fe,0x3f80,0x3ffff80,
3359 0x7e01803,0xfffff007,0xe03f003f,0x3f00000,0x0,0x0,0x0,0x0,0xfc0fc0,0x3ffe00,0xfe0003,0xffffc003,0xf81f01ff,0xff8003ff,0xffe01fff,
3360 0xff003f01,0xf01e0007,0x803ffff0,0xfff80,0x3c007e00,0x7800001f,0xc007f07f,0x1e007e,0xfc007ff,0xff801f83,0xf007ffff,0x800fc07c,
3361 0x7fffffe,0xf0003c0,0xf0000f0f,0x1e07,0xc007c0f8,0x7c01ff,0xfff8003c,0xf000,0x1e0,0xffc0,0x0,0xf0000,0x1,0xe0000000,0x0,0x780000,
3362 0x3e,0x0,0x78000,0x3c00,0xf000,0x7800000,0x1e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x3c000,0x0,0x0,0x0,0x0,0x0,0x1f,0x800000f0,0x1f80,
3363 0x0,0x0,0x7e0780,0x0,0x0,0x1f82000,0x0,0x0,0x0,0x7070,0x0,0x1f80f80,0x0,0x7fffff80,0x1f,0xffff8000,0x0,0x0,0x0,0x0,0x0,0x0,
3364 0x0,0x1,0xc3f80070,0x3f3f0007,0xf0000000,0x0,0x0,0x7f00,0x3e001f0,0x0,0x780000,0x180000,0x7f018000,0xf80,0x7c0003c,0x3e00,
3365 0x4001f0f8,0xfe00,0x400f00,0x0,0x0,0x0,0x7f000000,0xe0,0x38000000,0x1e,0x38,0x7800,0x0,0x1ffe1c00,0x0,0x0,0x38000078,0xf000000,
3366 0x1c00,0xe000,0x7f800,0xf000,0x1fc000,0xfe0000,0x7f00000,0x3f800001,0xfc00001f,0xf00001ff,0xffc03f81,0xf007ffff,0xc03ffffe,
3367 0x1fffff0,0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01fff,0xf800fe00,0x3c00fc1f,0x8007e0fc,0x3f07e0,0x1f83f00,0xfc1f800,
3368 0x3,0xf07fc0f0,0x3c0780,0x1e03c00,0xf01e000,0x780f8007,0xc01e0000,0x7e0fc0,0xf0000,0x3c0000,0x1c1c0003,0x87f0001f,0xf80003f,
3369 0xf8000000,0x0,0xf00,0x3c00,0x1c1c00,0x3e1f000,0xf00000,0x3c00001,0xc1c0003e,0x1f00003f,0xc0000e1f,0xc00003c0,0xf00,0x70700,
3370 0xe1fc00,0x7c3e000,0x0,0x0,0x78000001,0xe00000e0,0xe0001f0f,0x800003c0,0x1e0000,0x3e1f00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3371 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x3c1e0000,0x3c0f0001,0xff801e0f,
3372 0x1f00,0x1e0,0x3c0,0x1e000,0x3c1c1e0,0x0,0x0,0x0,0x0,0x78007c0,0x1f001f9e,0x3c001,0xf010003e,0x7780,0x3c00000,0xf800000,0xf007,
3373 0xc01f007c,0x1f80000,0x0,0x0,0x0,0x0,0xe003e0,0x7fff00,0x1ef0003,0xc007e007,0xc00301e0,0x1fc003c0,0x1e00,0x7c00,0x301e0007,
3374 0x80007800,0x780,0x3c00fc00,0x7800001f,0xe00ff07f,0x1e00f8,0x3e00780,0x1fc03e00,0xf807801f,0xc01f001c,0xf000,0xf0003c0,0xf0000f0f,
3375 0x1e03,0xc00f8078,0x780000,0xf0003c,0xf000,0x1e0,0x1f3e0,0x0,0x78000,0x1,0xe0000000,0x0,0x780000,0x3c,0x0,0x78000,0x0,0x0,
3376 0x7800000,0x1e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x3c000,0x0,0x0,0x0,0x0,0x0,0x1f,0xf0,0xf80,0x0,0x0,0xf80180,0x0,0x0,0x1e00000,
3377 0x0,0x0,0x0,0xe038,0x0,0x3e00380,0x0,0xfe0f0000,0x0,0xf0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xc0f00070,0x3b370003,0xe0000000,
3378 0x0,0x0,0x3e00,0x1e001e0,0x0,0x780000,0x180000,0x7c000000,0x780,0x780003c,0x3c00,0x0,0x7ffc0,0x780,0x0,0x0,0x3,0xffe00000,
3379 0x1c0,0x3c000000,0xe,0x38,0xf000,0x0,0x3ffe1c00,0x0,0x0,0x38000078,0xf000000,0x1c00,0xe000,0x7f000,0xf000,0x3de000,0x1ef0000,
3380 0xf780000,0x7bc00003,0xde00001e,0xf00003e7,0x80007c00,0x30078000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,
3381 0xe0001e03,0xfc00fe00,0x3c01f007,0xc00f803e,0x7c01f0,0x3e00f80,0x1f007c00,0x7,0xc01f80f0,0x3c0780,0x1e03c00,0xf01e000,0x78078007,
3382 0x801e0000,0x7803c0,0x78000,0x780000,0x380e0003,0x81e00000,0x1f,0xf0000000,0x0,0x780,0x7800,0x380e00,0x0,0x780000,0x7800003,
3383 0x80e00000,0x1ff,0x80000e07,0x800001e0,0x1e00,0xe0380,0xe07800,0x0,0x0,0x0,0x3c000003,0xc00001c0,0x70000000,0x780,0x1e0000,
3384 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3385 0x780000,0x3c1e0000,0x3c0e0007,0xfff01c07,0x1e00,0x1e0,0x780,0xf000,0x3e1c3e0,0x0,0x0,0x0,0x0,0xf0007c0,0x1f00181e,0x20000,
3386 0xf000001f,0xf780,0x3c00000,0x1f000000,0x1f00f,0x800f8078,0xf80000,0x0,0x0,0x0,0x0,0x8003e0,0x1fc0f80,0x1ef0003,0xc001e007,
3387 0x800101e0,0x7e003c0,0x1e00,0x7800,0x101e0007,0x80007800,0x780,0x3c00f800,0x7800001e,0xe00ef07f,0x801e00f0,0x1e00780,0x7c03c00,
3388 0x78078007,0xc01e0004,0xf000,0xf0003c0,0x78001e0f,0x1e03,0xe00f807c,0xf80000,0x1f0003c,0x7800,0x1e0,0x3e1f0,0x0,0x3c000,0x1,
3389 0xe0000000,0x0,0x780000,0x3c,0x0,0x78000,0x0,0x0,0x7800000,0x1e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x3c000,0x0,0x0,0x0,0x0,0x0,
3390 0x1e,0xf0,0x780,0x0,0x0,0x1f00080,0x0,0x0,0x3c00000,0x0,0x0,0x0,0x1e03c,0x0,0x3c00080,0x0,0xf80f0000,0x0,0x1f0000,0x0,0x0,
3391 0x0,0x0,0x0,0x0,0x0,0x0,0x70,0x3bf70003,0xe0000000,0x0,0x0,0x3e00,0x1f003e0,0x0,0x780000,0x180000,0x78000000,0x7c0,0xf80003c,
3392 0x3c00,0x0,0x1f01f0,0x780,0x0,0x0,0xf,0x80f80000,0x1c0,0x1c000000,0xe,0x38,0x1e000,0x0,0x7ffe1c00,0x0,0x0,0x380000f0,0x7800000,
3393 0x1c00,0xe000,0x7fc00,0xf000,0x3de000,0x1ef0000,0xf780000,0x7bc00003,0xde00001e,0xf00003c7,0x80007800,0x10078000,0x3c0000,
3394 0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x7e00ff00,0x3c01e003,0xc00f001e,0x7800f0,0x3c00780,0x1e003c00,
3395 0x7,0x800f00f0,0x3c0780,0x1e03c00,0xf01e000,0x7807c00f,0x801e0000,0xf803c0,0x3c000,0xf00000,0x780f0000,0x0,0x7,0xc0000000,
3396 0x0,0x3c0,0xf000,0x780f00,0x0,0x3c0000,0xf000007,0x80f00000,0x7ff,0xc0000000,0xf0,0x3c00,0x1e03c0,0x0,0x0,0x0,0x0,0x1e000007,
3397 0x800003c0,0x78000000,0xf00,0x1e0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3398 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x3c1e0000,0x3c1e001f,0xfff03803,0x80001e00,0x1e0,0x780,0xf000,0xf9cf80,
3399 0x0,0x0,0x0,0x0,0xf000780,0xf00001e,0x0,0xf800000f,0xe780,0x3c00000,0x1e000000,0x1e00f,0x78078,0x7c0000,0x0,0x0,0x0,0x0,0x1e0,
3400 0x3f003c0,0x1ef0003,0xc000f00f,0x800001e0,0x1f003c0,0x1e00,0xf000,0x1e0007,0x80007800,0x780,0x3c01f000,0x7800001e,0xe00ef07f,
3401 0x801e01f0,0x1e00780,0x3c07c00,0x78078003,0xc03e0000,0xf000,0xf0003c0,0x78001e0f,0x1e01,0xf01f003c,0xf00000,0x3e0003c,0x7800,
3402 0x1e0,0x7c0f8,0x0,0x0,0x1,0xe0000000,0x0,0x780000,0x3c,0x0,0x78000,0x0,0x0,0x7800000,0x1e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x3c000,
3403 0x0,0x0,0x0,0x0,0x0,0x1e,0xf0,0x780,0x0,0x0,0x1e00000,0x0,0x0,0x3c00000,0x0,0x8,0x40,0x0,0x7e0000,0x7c00000,0x1,0xf00f0000,
3404 0x0,0x3e0000,0x0,0x3f,0xfc0,0xfc3f0,0xfc3f0,0x0,0x0,0x0,0x70,0x39e70000,0x0,0x0,0x0,0x0,0xf003c0,0x0,0x0,0x180000,0xf8000000,
3405 0x3c0,0xf00003c,0x3c00,0x0,0x3c0078,0x7ff80,0x0,0x0,0x1e,0x3c0000,0x1c0,0x1c000000,0xe,0xf0,0x0,0x0,0x7ffe1c00,0x0,0x0,0x380000f0,
3406 0x7800000,0x1c00,0xe000,0x3c00,0x0,0x3de000,0x1ef0000,0xf780000,0x7bc00003,0xde00001e,0xf00003c7,0x8000f800,0x78000,0x3c0000,
3407 0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x1f00ff00,0x3c03e003,0xc01f001e,0xf800f0,0x7c00780,0x3e003c00,
3408 0xf,0x800f80f0,0x3c0780,0x1e03c00,0xf01e000,0x7803c00f,0x1fffc0,0xf001e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3409 0x0,0x0,0x307,0xe0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1e0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3410 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x3c1e0000,0x781e003f,0xfff03803,
3411 0x80001e00,0x1e0,0xf80,0xf000,0x3dde00,0x0,0x0,0x0,0x0,0xf000f00,0x780001e,0x0,0x7800000f,0x1e780,0x3c00000,0x3e000000,0x3e00f,
3412 0x780f0,0x7c0000,0x0,0x0,0x0,0x0,0x1e0,0x7c001e0,0x3ef8003,0xc000f00f,0x1e0,0xf003c0,0x1e00,0xf000,0x1e0007,0x80007800,0x780,
3413 0x3c03e000,0x7800001e,0xf01ef07b,0xc01e01e0,0xf00780,0x3e07800,0x3c078003,0xe03c0000,0xf000,0xf0003c0,0x78001e0f,0x1e00,0xf01e003e,
3414 0x1f00000,0x3c0003c,0x7800,0x1e0,0x78078,0x0,0x0,0x1,0xe0000000,0x0,0x780000,0x3c,0x0,0x78000,0x0,0x0,0x7800000,0x1e00000,
3415 0x0,0x0,0x0,0x0,0x0,0x0,0x3c000,0x0,0x0,0x0,0x0,0x0,0x1e,0xf0,0x780,0x0,0x0,0x1e00000,0x0,0x0,0x3c00000,0x0,0x18,0xc0,0x0,
3416 0xe70000,0x7800000,0x1,0xe00f0000,0x0,0x3c0000,0x0,0x3f,0xfc0,0xfc1f0,0x1f83f0,0x0,0x0,0x0,0x70,0x39e70000,0x0,0x0,0x0,0x0,
3417 0xf807c0,0x0,0x0,0x180000,0xf0000000,0x3e0,0x1f00003c,0x3e00,0x0,0x70001c,0x3fff80,0x0,0x0,0x38,0xe0000,0x1c0,0x1c000078,
3418 0x1c,0x1fe0,0x0,0x0,0xfffe1c00,0x0,0x0,0x380000f0,0x7800000,0x1c00,0xe000,0xe00,0x0,0x7df000,0x3ef8000,0x1f7c0000,0xfbe00007,
3419 0xdf00003c,0x780003c7,0x8000f000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0xf00f780,
3420 0x3c03c001,0xe01e000f,0xf00078,0x78003c0,0x3c001e00,0xf,0xf80f0,0x3c0780,0x1e03c00,0xf01e000,0x7803e01f,0x1ffff8,0xf001e0,
3421 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0xe0000000,0x0,0x0,0x0,0x0,0x0,0x0,0xc000,0x0,0x0,0x0,0x0,0x1e0000,
3422 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3423 0x780000,0x3c1e0000,0x781e003e,0x30703803,0x80001e00,0x1e0,0xf00,0x7800,0xff800,0x1e0000,0x0,0x0,0x0,0x1e000f00,0x780001e,
3424 0x0,0x7800000f,0x3c780,0x3c00000,0x3c000000,0x3c00f,0x780f0,0x3c0000,0x0,0x0,0x2000000,0x800000,0x1e0,0x78000e0,0x3c78003,
3425 0xc000f01e,0x1e0,0xf803c0,0x1e00,0x1e000,0x1e0007,0x80007800,0x780,0x3c07c000,0x7800001e,0x701cf07b,0xc01e01e0,0xf00780,0x1e07800,
3426 0x3c078001,0xe03c0000,0xf000,0xf0003c0,0x7c003e0f,0x1e00,0xf83e001e,0x1e00000,0x7c0003c,0x3c00,0x1e0,0xf807c,0x0,0x0,0x1fe0001,
3427 0xe1fc0000,0x7f00003,0xf8780007,0xf000003c,0x7f0,0x783f0,0x0,0x0,0x7800000,0x1e00000,0x3e0f8000,0xfc00007,0xf8000007,0xf00001fc,
3428 0xf,0xc0003fc0,0x3c000,0x0,0x0,0x0,0x0,0x0,0x1e,0xf0,0x780,0x0,0x0,0x3c00000,0x0,0x0,0x3c00000,0x0,0x18,0xc0,0x0,0x1818000,
3429 0x7800000,0x1,0xe00f0000,0x0,0x7c0000,0x0,0x1f,0x80001f80,0x7c1f8,0x1f83e0,0x0,0x0,0x0,0x70,0x38c70007,0xf8000000,0x7f03,
3430 0xf0000000,0x0,0x780780,0x0,0x0,0xfe0000,0xf0000000,0x1e0,0x1e00003c,0x3f00,0x0,0xe07f0e,0x7fff80,0x0,0x0,0x70,0x70000,0x1c0,
3431 0x1c000078,0x3c,0x1fc0,0x0,0x0,0xfffe1c00,0x0,0x0,0x380000f0,0x7800000,0x1c00,0xe000,0xe00,0x0,0x78f000,0x3c78000,0x1e3c0000,
3432 0xf1e00007,0x8f00003c,0x78000787,0x8001e000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,
3433 0xf80f780,0x3c03c001,0xe01e000f,0xf00078,0x78003c0,0x3c001e00,0xf,0x1f80f0,0x3c0780,0x1e03c00,0xf01e000,0x7801e01e,0x1ffffc,
3434 0xf007e0,0x3fc000,0x1fe0000,0xff00000,0x7f800003,0xfc00001f,0xe0000fc0,0xfc00007f,0xfe0,0x7f00,0x3f800,0x1fc000,0x0,0x0,0x0,
3435 0x1,0xf000001f,0x80000ff0,0x7f80,0x3fc00,0x1fe000,0xff0000,0x1f80000,0x1fc1e000,0x0,0x0,0x0,0x0,0x1e1fc0,0x0,0x0,0x0,0x0,
3436 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x3c1e0000,
3437 0x781c007c,0x30003803,0x80001f00,0x1e0,0xf00,0x7800,0x7f000,0x1e0000,0x0,0x0,0x0,0x1e000f00,0x780001e,0x0,0x7800000f,0x3c780,
3438 0x3c00000,0x3c000000,0x3c00f,0x780f0,0x3c0000,0x0,0x0,0x1e000000,0xf00000,0x3e0,0xf0000e0,0x3c78003,0xc000f01e,0x1e0,0x7803c0,
3439 0x1e00,0x1e000,0x1e0007,0x80007800,0x780,0x3c0f8000,0x7800001e,0x701cf079,0xe01e01e0,0xf00780,0x1e07800,0x3c078001,0xe03c0000,
3440 0xf000,0xf0003c0,0x3c003c0f,0x3e00,0x787c001f,0x3e00000,0xf80003c,0x3c00,0x1e0,0x1f003e,0x0,0x0,0x1fffc001,0xe7ff0000,0x3ffe000f,
3441 0xfe78003f,0xfc001fff,0xfe001ffc,0xf0078ffc,0x1ffc00,0x7ff000,0x7800f80,0x1e0000f,0x7f1fc01e,0x3ff0001f,0xfe00079f,0xfc0007ff,
3442 0x3c003c7f,0xf001fff8,0x1fffff0,0x3c003c0,0xf0000f1e,0xf1f,0x7c1f0,0x1f00ff,0xffe0001e,0xf0,0x780,0x0,0x0,0x3c00000,0x100000,
3443 0x0,0x7800000,0x0,0x18,0xc0,0x0,0x1818000,0x7800000,0x1,0xe00f0000,0x1000000,0xf80000,0x40000002,0xf,0x80001f00,0x7e0f8,0x1f07c0,
3444 0x0,0x0,0x0,0x70,0x38c7003f,0xff000000,0xff8f,0xf8000100,0xffffe,0x7c0f80,0x0,0x0,0x3ffc000,0xf0000020,0x1001f0,0x3c00003c,
3445 0x1f80,0x0,0x1c3ffc7,0x7c0780,0x0,0x0,0xe3,0xff038000,0xe0,0x38000078,0x78,0x1ff0,0x0,0x3c003c0,0xfffe1c00,0x0,0x0,0x380000f0,
3446 0x7800000,0x1c00,0xe000,0xe00,0xf000,0x78f000,0x3c78000,0x1e3c0000,0xf1e00007,0x8f00003c,0x78000787,0x8001e000,0x78000,0x3c0000,
3447 0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x780f3c0,0x3c03c001,0xe01e000f,0xf00078,0x78003c0,0x3c001e00,
3448 0x4000200f,0x3f80f0,0x3c0780,0x1e03c00,0xf01e000,0x7801f03e,0x1ffffe,0xf01fe0,0x3fff800,0x1fffc000,0xfffe0007,0xfff0003f,
3449 0xff8001ff,0xfc003ff3,0xfe0003ff,0xe0007ff8,0x3ffc0,0x1ffe00,0xfff000,0x3ff80001,0xffc0000f,0xfe00007f,0xf000003f,0xf8003c7f,
3450 0xe0003ffc,0x1ffe0,0xfff00,0x7ff800,0x3ffc000,0x1f80000,0xfff1c03c,0x3c01e0,0x1e00f00,0xf007800,0x781f0001,0xf01e7ff0,0x7c0007c,
3451 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,
3452 0x3c1e003f,0xfffff078,0x30003803,0x80000f00,0x1e0,0x1f00,0x7800,0x7f000,0x1e0000,0x0,0x0,0x0,0x3c000f00,0x780001e,0x0,0x7800000f,
3453 0x78780,0x3c00000,0x3c000000,0x7c00f,0x780f0,0x3c0007,0xe000003f,0x0,0xfe000000,0xfe0000,0x3c0,0x1f000070,0x7c7c003,0xc000f01e,
3454 0x1e0,0x7803c0,0x1e00,0x1e000,0x1e0007,0x80007800,0x780,0x3c1f0000,0x7800001e,0x783cf079,0xe01e03c0,0xf00780,0x1e0f000,0x3c078001,
3455 0xe03c0000,0xf000,0xf0003c0,0x3c003c07,0x81f03c00,0x7c7c000f,0x87c00000,0xf00003c,0x1e00,0x1e0,0x3e001f,0x0,0x0,0x3fffe001,
3456 0xefff8000,0x7fff001f,0xff78007f,0xfe001fff,0xfe003ffe,0xf0079ffe,0x1ffc00,0x7ff000,0x7801f00,0x1e0000f,0xffbfe01e,0x7ff8003f,
3457 0xff0007bf,0xfe000fff,0xbc003cff,0xf803fffc,0x1fffff0,0x3c003c0,0x78001e1e,0xf0f,0x800f80f0,0x1e00ff,0xffe0001e,0xf0,0x780,
3458 0x0,0x0,0x3c00000,0x380000,0x0,0x7800000,0x0,0x18,0xc0,0x0,0x1008000,0x7800000,0x3,0xe00f0000,0x3800000,0xf00000,0xe0000007,
3459 0xf,0x80001f00,0x3e0f8,0x1e07c0,0x0,0x0,0x0,0x70,0x3807007f,0xff800000,0x1ffdf,0xfc000380,0xffffe,0x3e1f00,0x0,0x0,0xfffe000,
3460 0xf0000030,0x3800f8,0x7c00003c,0xfc0,0x0,0x18780c3,0xf00780,0x80100,0x0,0xc3,0xffc18000,0xf0,0x78000078,0xf0,0xf0,0x0,0x3c003c0,
3461 0xfffe1c00,0x0,0x0,0x380000f0,0x7800801,0x1c00,0xe000,0x1e00,0xf000,0xf8f800,0x7c7c000,0x3e3e0001,0xf1f0000f,0x8f80007c,0x7c000787,
3462 0x8001e000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x780f3c0,0x3c078001,0xe03c000f,
3463 0x1e00078,0xf0003c0,0x78001e00,0xe000701f,0x3fc0f0,0x3c0780,0x1e03c00,0xf01e000,0x7800f87c,0x1e007f,0xf07e00,0x7fffc00,0x3fffe001,
3464 0xffff000f,0xfff8007f,0xffc003ff,0xfe007ff7,0xff0007ff,0xf000fffc,0x7ffe0,0x3fff00,0x1fff800,0x3ff80001,0xffc0000f,0xfe00007f,
3465 0xf00000ff,0xf8003cff,0xf0007ffe,0x3fff0,0x1fff80,0xfffc00,0x7ffe000,0x1f80001,0xfffb803c,0x3c01e0,0x1e00f00,0xf007800,0x780f0001,
3466 0xe01efff8,0x3c00078,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3467 0x0,0x0,0x0,0x0,0x0,0x780000,0x3c1e003f,0xfffff078,0x30001c07,0xf80,0x1e0,0x1e00,0x3c00,0xff800,0x1e0000,0x0,0x0,0x0,0x3c001e00,
3468 0x3c0001e,0x0,0x7800001e,0x70780,0x3c00000,0x78000000,0x78007,0x800f00f0,0x3e0007,0xe000003f,0x3,0xfe000000,0xff8000,0x7c0,
3469 0x1e000070,0x783c003,0xc001f01e,0x1e0,0x7803c0,0x1e00,0x1e000,0x1e0007,0x80007800,0x780,0x3c3e0000,0x7800001e,0x3838f079,
3470 0xe01e03c0,0x780780,0x1e0f000,0x1e078001,0xe03c0000,0xf000,0xf0003c0,0x3c007c07,0x81f03c00,0x3ef80007,0x87800000,0x1f00003c,
3471 0x1e00,0x1e0,0x7c000f,0x80000000,0x0,0x3ffff001,0xffffc000,0xffff003f,0xff7800ff,0xff001fff,0xfe007ffe,0xf007bffe,0x1ffc00,
3472 0x7ff000,0x7803e00,0x1e0000f,0xffffe01e,0xfff8007f,0xff8007ff,0xff001fff,0xbc003dff,0xf807fffc,0x1fffff0,0x3c003c0,0x78001e0f,
3473 0x1e07,0xc01f00f0,0x1e00ff,0xffe0001e,0xf0,0x780,0x0,0x0,0x7c00000,0x7c0000,0x0,0x7800000,0x0,0x18,0xc0,0x0,0x1018000,0x7800000,
3474 0x3,0xc00f0000,0x7c00000,0x1f00001,0xf000000f,0x80000007,0xc0003e00,0x1e07c,0x3e0780,0x0,0x0,0x0,0x70,0x380700ff,0xff800000,
3475 0x3ffff,0xfe0007c0,0xffffe,0x1e1e00,0x0,0x780000,0x1fffe000,0xf0000078,0x7c0078,0x7800003c,0xff0,0x0,0x38e0003,0x80f00780,
3476 0x180300,0x0,0x1c3,0x81e1c000,0x7f,0xf0000078,0x1e0,0x38,0x0,0x3c003c0,0xfffe1c00,0x0,0x0,0x380000f0,0x7800c01,0x80001c00,
3477 0xe000,0x603e00,0xf000,0xf07800,0x783c000,0x3c1e0001,0xe0f0000f,0x7800078,0x3c000f87,0x8001e000,0x78000,0x3c0000,0x1e00000,
3478 0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x780f3c0,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f01,0xf000f81e,
3479 0x7bc0f0,0x3c0780,0x1e03c00,0xf01e000,0x78007878,0x1e001f,0xf0f800,0x7fffe00,0x3ffff001,0xffff800f,0xfffc007f,0xffe003ff,
3480 0xff007fff,0xff800fff,0xf001fffe,0xffff0,0x7fff80,0x3fffc00,0x3ff80001,0xffc0000f,0xfe00007f,0xf00001ff,0xfc003dff,0xf000ffff,
3481 0x7fff8,0x3fffc0,0x1fffe00,0xffff000,0x1f80003,0xffff803c,0x3c01e0,0x1e00f00,0xf007800,0x780f0001,0xe01ffffc,0x3c00078,0x0,
3482 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,
3483 0x3c1e003f,0xfffff078,0x30001e0f,0x300780,0x1e0,0x1e00,0x3c00,0x3dde00,0x1e0000,0x0,0x0,0x0,0x78001e00,0x3c0001e,0x0,0xf800003e,
3484 0xf0780,0x3dfc000,0x783f8000,0xf8007,0xc01f00f0,0x3e0007,0xe000003f,0x1f,0xfc000000,0x7ff000,0xf80,0x3e007c70,0x783c003,0xc001e03c,
3485 0x1e0,0x3c03c0,0x1e00,0x3c000,0x1e0007,0x80007800,0x780,0x3c7c0000,0x7800001e,0x3878f078,0xf01e03c0,0x780780,0x1e0f000,0x1e078001,
3486 0xe03e0000,0xf000,0xf0003c0,0x1e007807,0x83f03c00,0x3ef00007,0xcf800000,0x3e00003c,0xf00,0x1e0,0xf80007,0xc0000000,0x0,0x3e01f801,
3487 0xfe07e001,0xf80f007e,0x7f801f8,0x1f801fff,0xfe00fc0f,0xf007f83f,0x1ffc00,0x7ff000,0x7807c00,0x1e0000f,0x87e1e01f,0xe0fc00fc,
3488 0xfc007f8,0x1f803f03,0xfc003df0,0x3807e03c,0x1fffff0,0x3c003c0,0x78003e0f,0x1e03,0xe03e00f8,0x3e00ff,0xffe0001e,0xf0,0x780,
3489 0x0,0x0,0x7800000,0xfe0000,0x0,0x7800000,0x0,0x18,0xc0,0x0,0x1818000,0x7c00000,0x3,0xc00f0000,0xfe00000,0x3e00003,0xf800001f,
3490 0xc0000007,0xc0003e00,0x1e03c,0x3c0f80,0x0,0x0,0x0,0x70,0x380700fc,0x7800000,0x7c1fe,0x3e000fe0,0xffffe,0x1f3e00,0x0,0x780000,
3491 0x3f98e000,0xf000003c,0xfcf8007c,0xf800003c,0x3ffc,0x0,0x31c0001,0x80f00f80,0x380700,0x0,0x183,0x80e0c000,0x3f,0xe0000078,
3492 0x3c0,0x38,0x0,0x3c003c0,0xfffe1c00,0x0,0x0,0x38000078,0xf000e01,0xc003ffe0,0x1fff00,0x7ffc00,0xf000,0xf07800,0x783c000,0x3c1e0001,
3493 0xe0f0000f,0x7800078,0x3c000f07,0x8003c000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,
3494 0x3c0f1e0,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0xf801f01e,0xf3c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78007cf8,
3495 0x1e000f,0x80f0f000,0x7c03f00,0x3e01f801,0xf00fc00f,0x807e007c,0x3f003e0,0x1f80707f,0x8f801f80,0xf003f03f,0x1f81f8,0xfc0fc0,
3496 0x7e07e00,0x3ff80001,0xffc0000f,0xfe00007f,0xf00003ff,0xfc003fc1,0xf801f81f,0x800fc0fc,0x7e07e0,0x3f03f00,0x1f81f800,0x1f80007,
3497 0xe07f003c,0x3c01e0,0x1e00f00,0xf007800,0x780f8003,0xe01fe07e,0x3e000f8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3498 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x3f,0xfffff078,0x30000ffe,0x1f007c0,0x0,0x1e00,
3499 0x3c00,0xf9cf80,0x1e0000,0x0,0x0,0x0,0x78001e00,0x3c0001e,0x0,0xf00000fc,0x1e0780,0x3fff800,0x78ffe000,0xf0003,0xe03e00f0,
3500 0x3e0007,0xe000003f,0x7f,0xe01fffff,0xf00ffc00,0x1f80,0x3c01ff70,0x783c003,0xc007e03c,0x1e0,0x3c03c0,0x1e00,0x3c000,0x1e0007,
3501 0x80007800,0x780,0x3cfc0000,0x7800001e,0x3c78f078,0xf01e03c0,0x780780,0x3e0f000,0x1e078003,0xc01f0000,0xf000,0xf0003c0,0x1e007807,
3502 0x83f83c00,0x1ff00003,0xcf000000,0x3e00003c,0xf00,0x1e0,0x0,0x0,0x0,0x20007801,0xfc03e003,0xe003007c,0x3f803e0,0x7c0003c,
3503 0xf807,0xf007e00f,0x3c00,0xf000,0x780f800,0x1e0000f,0x87e1f01f,0x803c00f8,0x7c007f0,0xf803e01,0xfc003f80,0x80f8004,0x3c000,
3504 0x3c003c0,0x3c003c0f,0x1e03,0xe03e0078,0x3c0000,0x7c0001e,0xf0,0x780,0x0,0x0,0x3ffff800,0x1ff0000,0x0,0x7800000,0x0,0x18,
3505 0xc0,0x0,0x1818000,0x3e00000,0x3,0xc00f0000,0x1ff00000,0x3e00007,0xfc00003f,0xe0000003,0xc0003c00,0xf03c,0x3c0f00,0x0,0x0,
3506 0x0,0x70,0x380701f0,0x800000,0x780fc,0x1e001ff0,0x7c,0xf3c00,0x0,0x780000,0x7e182000,0xf000001f,0xfff00ffc,0xffc0003c,0x3cfe,
3507 0x0,0x31c0001,0x80f01f80,0x780f00,0x0,0x183,0x80e0c000,0xf,0x80000078,0x780,0x38,0x0,0x3c003c0,0x7ffe1c00,0x0,0x0,0x38000078,
3508 0xf000f01,0xe003ffe0,0x1fff00,0x7ff800,0xf000,0xf07800,0x783c000,0x3c1e0001,0xe0f0000f,0x78000f8,0x3e000f07,0x8003c000,0x78000,
3509 0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x3c0f1e0,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,
3510 0x78000f00,0x7c03e01e,0x1e3c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78003cf0,0x1e0007,0x80f1e000,0x4000f00,0x20007801,0x3c008,
3511 0x1e0040,0xf00200,0x780403f,0x7803e00,0x3007c00f,0x803e007c,0x1f003e0,0xf801f00,0x780000,0x3c00000,0x1e000000,0xf00007f0,
3512 0x3e003f00,0x7801f00f,0x800f807c,0x7c03e0,0x3e01f00,0x1f00f800,0x1f80007,0xc03e003c,0x3c01e0,0x1e00f00,0xf007800,0x78078003,
3513 0xc01fc03e,0x1e000f0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3514 0x0,0x0,0x0,0x0,0x0,0x780000,0x0,0xf078007c,0x300007fc,0x7e00fe0,0x0,0x1e00,0x3c00,0x3e1c3e0,0x1e0000,0x0,0x0,0x0,0xf0001e00,
3515 0x3c0001e,0x1,0xf000fff8,0x1e0780,0x3fffe00,0x79fff000,0x1f0001,0xfffc00f0,0x7e0007,0xe000003f,0x3ff,0x801fffff,0xf003ff80,
3516 0x3f00,0x3c03fff0,0xf01e003,0xffffc03c,0x1e0,0x3c03ff,0xffc01fff,0xfe03c000,0x1fffff,0x80007800,0x780,0x3df80000,0x7800001e,
3517 0x1c70f078,0x781e03c0,0x780780,0x3c0f000,0x1e078007,0xc01f8000,0xf000,0xf0003c0,0x1e007807,0x83f83c00,0xfe00003,0xff000000,
3518 0x7c00003c,0x780,0x1e0,0x0,0x0,0x0,0x7c01,0xf801f007,0xc00100f8,0x1f803c0,0x3c0003c,0x1f003,0xf007c00f,0x80003c00,0xf000,
3519 0x783f000,0x1e0000f,0x3c0f01f,0x3e01f0,0x3e007e0,0x7c07c00,0xfc003f00,0xf0000,0x3c000,0x3c003c0,0x3c003c0f,0x1e01,0xf07c007c,
3520 0x7c0000,0xfc0001e,0xf0,0x780,0x0,0x0,0x3ffff000,0x3838000,0x0,0x7800000,0x0,0x18,0xc0,0x0,0xff0000,0x3f00000,0x3,0xc00fff00,
3521 0x38380000,0x7c0000e,0xe000070,0x70000001,0xe0003c00,0xf01e,0x780e00,0x0,0x0,0x0,0x0,0x1e0,0x0,0x780f8,0xf003838,0xfc,0xffc00,
3522 0x0,0x780000,0x7c180000,0xf000000f,0xffe00fff,0xffc0003c,0x783f,0x80000000,0x6380000,0xc0f83f80,0xf81f00,0x0,0x303,0x80e06000,
3523 0x0,0x78,0xf00,0x78,0x0,0x3c003c0,0x7ffe1c00,0x0,0x0,0x3800003c,0x3e000f81,0xf003ffe0,0x1fff00,0x1fc000,0xf000,0x1e03c00,
3524 0xf01e000,0x780f0003,0xc078001e,0x3c000f0,0x1e000f07,0xff83c000,0x7ffff,0x803ffffc,0x1ffffe0,0xfffff00,0xf00000,0x7800000,
3525 0x3c000001,0xe0001e00,0x3c0f0f0,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0x3e07c01e,0x1e3c0f0,0x3c0780,0x1e03c00,
3526 0xf01e000,0x78003ff0,0x1e0007,0x80f1e000,0xf80,0x7c00,0x3e000,0x1f0000,0xf80000,0x7c0001e,0x3c07c00,0x10078007,0x803c003c,
3527 0x1e001e0,0xf000f00,0x780000,0x3c00000,0x1e000000,0xf00007c0,0x1e003e00,0x7c03e007,0xc01f003e,0xf801f0,0x7c00f80,0x3e007c00,
3528 0xf,0x801f003c,0x3c01e0,0x1e00f00,0xf007800,0x7807c007,0xc01f801f,0x1f001f0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3529 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x0,0xe078003c,0x300001f0,0x3f801ff0,0x0,
3530 0x3c00,0x1e00,0x3c1c1e0,0x1e0000,0x0,0x0,0x0,0xf0001e0f,0x3c0001e,0x3,0xe000fff0,0x3c0780,0x3ffff00,0x7bfff800,0x1e0000,0x7ff00078,
3531 0x7e0007,0xe000003f,0x1ffc,0x1fffff,0xf0007ff0,0x7e00,0x3c07c3f0,0xf01e003,0xffff003c,0x1e0,0x3c03ff,0xffc01fff,0xfe03c000,
3532 0x1fffff,0x80007800,0x780,0x3ffc0000,0x7800001e,0x1ef0f078,0x781e03c0,0x780780,0x7c0f000,0x1e07801f,0x800ff000,0xf000,0xf0003c0,
3533 0xf00f807,0x83b83c00,0xfc00001,0xfe000000,0xf800003c,0x780,0x1e0,0x0,0x0,0x0,0x3c01,0xf000f007,0xc00000f0,0xf80780,0x3c0003c,
3534 0x1e001,0xf007c007,0x80003c00,0xf000,0x787e000,0x1e0000f,0x3c0f01f,0x1e01e0,0x1e007c0,0x3c07800,0x7c003f00,0xf0000,0x3c000,
3535 0x3c003c0,0x3e007c07,0x80003c00,0xf8f8003c,0x780000,0xf80001e,0xf0,0x780,0x0,0x0,0x7ffff000,0x601c000,0x3,0xffff0000,0x0,
3536 0xfff,0xf8007fff,0xc0000000,0x7e003c,0x1fe0000,0xc0003,0xc00fff00,0x601c0000,0xf800018,0x70000c0,0x38000001,0xe0007800,0x701e,
3537 0x701e00,0x0,0x0,0x0,0x0,0x1e0,0x6,0x700f8,0xf00601c,0xf8,0x7f800,0x0,0x780000,0xf8180000,0xf000000f,0x87c00fff,0xffc0003c,
3538 0xf01f,0xc0000000,0x6380000,0xc07ff780,0x1f03e03,0xfffffe00,0x303,0x81c06000,0x0,0x1ffff,0xfe001e00,0x180f8,0x0,0x3c003c0,
3539 0x3ffe1c00,0x3f00000,0x0,0x3800003f,0xfe0007c0,0xf8000000,0x18000000,0xc0000006,0x1f000,0x1e03c00,0xf01e000,0x780f0003,0xc078001e,
3540 0x3c000f0,0x1e001f07,0xff83c000,0x7ffff,0x803ffffc,0x1ffffe0,0xfffff00,0xf00000,0x7800000,0x3c000001,0xe000fff8,0x3c0f0f0,
3541 0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0x1f0f801e,0x3c3c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78001fe0,0x1e0007,
3542 0x80f1e000,0x780,0x3c00,0x1e000,0xf0000,0x780000,0x3c0001e,0x3c07c00,0xf0007,0x8078003c,0x3c001e0,0x1e000f00,0x780000,0x3c00000,
3543 0x1e000000,0xf0000f80,0x1f003e00,0x3c03c003,0xc01e001e,0xf000f0,0x7800780,0x3c003c00,0xf,0x3f003c,0x3c01e0,0x1e00f00,0xf007800,
3544 0x7803c007,0x801f000f,0xf001e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3545 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1,0xe078003f,0xb0000000,0xfc003cf0,0x0,0x3c00,0x1e00,0x101c040,0x1e0000,0x0,0x0,0x1,
3546 0xe0001e1f,0x83c0001e,0x7,0xe000fff0,0x3c0780,0x3c03f80,0x7fc0fc00,0x1e0000,0xfff80078,0xfe0007,0xe000003f,0x7fe0,0x1fffff,
3547 0xf0000ffc,0xfc00,0x780f81f0,0xf01e003,0xffff003c,0x1e0,0x3c03ff,0xffc01fff,0xfe03c000,0x1fffff,0x80007800,0x780,0x3ffc0000,
3548 0x7800001e,0x1ef0f078,0x3c1e03c0,0x780780,0x1fc0f000,0x1e07ffff,0x7ff00,0xf000,0xf0003c0,0xf00f007,0xc3b87c00,0x7c00001,0xfe000000,
3549 0xf800003c,0x3c0,0x1e0,0x0,0x0,0x0,0x3c01,0xf000f007,0x800000f0,0xf80780,0x1e0003c,0x1e001,0xf0078007,0x80003c00,0xf000,0x78fc000,
3550 0x1e0000f,0x3c0f01e,0x1e01e0,0x1e007c0,0x3c07800,0x7c003e00,0xf0000,0x3c000,0x3c003c0,0x1e007807,0x80003c00,0x7df0003c,0x780000,
3551 0x1f00001e,0xf0,0x780,0x0,0x0,0x7800000,0xe7ce000,0x3,0xffff0000,0x0,0xfff,0xf8007fff,0xc0000000,0x1f0,0xffe000,0x1c0003,
3552 0xc00fff00,0xe7ce0000,0xf800039,0xf38001cf,0x9c000000,0xe0007800,0x780e,0x701c00,0x0,0x0,0x0,0x0,0x1e0,0x7,0xf0078,0xf00e7ce,
3553 0x1f0,0x7f800,0x0,0x780000,0xf0180000,0xf000000e,0x1c0001f,0xe000003c,0xf007,0xe0000000,0x6380000,0xc03fe780,0x3e07c03,0xfffffe00,
3554 0x303,0xffc06000,0x0,0x1ffff,0xfe003ffe,0x1fff0,0x0,0x3c003c0,0x1ffe1c00,0x3f00000,0x7,0xffc0001f,0xfc0003e0,0x7c000001,0xfc00000f,
3555 0xe000007f,0x1e000,0x1e03c00,0xf01e000,0x780f0003,0xc078001e,0x3c000f0,0x1e001e07,0xff83c000,0x7ffff,0x803ffffc,0x1ffffe0,
3556 0xfffff00,0xf00000,0x7800000,0x3c000001,0xe000fff8,0x3c0f078,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0xf9f001e,
3557 0x783c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78001fe0,0x1e0007,0x80f1e000,0x780,0x3c00,0x1e000,0xf0000,0x780000,0x3c0001e,0x3c07800,
3558 0xf0003,0xc078001e,0x3c000f0,0x1e000780,0x780000,0x3c00000,0x1e000000,0xf0000f00,0xf003c00,0x3c03c003,0xc01e001e,0xf000f0,
3559 0x7800780,0x3c003c00,0xf,0x7f003c,0x3c01e0,0x1e00f00,0xf007800,0x7803c007,0x801f000f,0xf001e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3560 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1,0xe070001f,0xf8000007,
3561 0xf0007cf8,0x7800000,0x3c00,0x1e00,0x1c000,0x1e0000,0x0,0x0,0x1,0xe0001e1f,0x83c0001e,0xf,0xc000fff8,0x780780,0x2000f80,0x7f803e00,
3562 0x3e0003,0xfffe007c,0x1fe0000,0x0,0x3ff00,0x0,0x1ff,0x8001f000,0x780f00f0,0x1f00f003,0xffffc03c,0x1e0,0x3c03ff,0xffc01fff,
3563 0xfe03c00f,0xf81fffff,0x80007800,0x780,0x3ffe0000,0x7800001e,0xee0f078,0x3c1e03c0,0x7807ff,0xff80f000,0x1e07fffe,0x3ffe0,
3564 0xf000,0xf0003c0,0xf00f003,0xc7bc7800,0xfc00000,0xfc000001,0xf000003c,0x3c0,0x1e0,0x0,0x0,0x0,0x3c01,0xe000f80f,0x800001e0,
3565 0xf80f00,0x1e0003c,0x3c000,0xf0078007,0x80003c00,0xf000,0x79f8000,0x1e0000f,0x3c0f01e,0x1e03c0,0x1f00780,0x3e0f000,0x7c003e00,
3566 0xf0000,0x3c000,0x3c003c0,0x1e007807,0x81e03c00,0x7df0003e,0xf80000,0x3e00003e,0xf0,0x7c0,0xfc000,0x80000000,0x7800000,0x1e7cf000,
3567 0x3,0xffff0000,0x0,0x18,0xc0,0x0,0xf80,0x7ffc00,0x380003,0xc00fff01,0xe7cf0000,0x1f000079,0xf3c003cf,0x9e000000,0xe0007000,
3568 0x380e,0xe01c00,0x0,0x0,0x0,0x0,0x1e0,0x3,0x800f0078,0xf01e7cf,0x3e0,0x3f000,0x0,0x780000,0xf018001f,0xfff8001e,0x1e0000f,
3569 0xc000003c,0xf003,0xe0000000,0x6380000,0xc00fc780,0x7c0f803,0xfffffe00,0x303,0xfe006000,0x0,0x1ffff,0xfe003ffe,0x1ffe0,0x0,
3570 0x3c003c0,0xffe1c00,0x3f00000,0x7,0xffc00007,0xf00001f0,0x3e00001f,0xfc0000ff,0xe00007ff,0x3e000,0x3e01e00,0x1f00f000,0xf8078007,
3571 0xc03c003e,0x1e001e0,0xf001e07,0xff83c000,0x7ffff,0x803ffffc,0x1ffffe0,0xfffff00,0xf00000,0x7800000,0x3c000001,0xe000fff8,
3572 0x3c0f078,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0x7fe001e,0xf03c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78000fc0,
3573 0x1e0007,0x80f1f000,0x780,0x3c00,0x1e000,0xf0000,0x780000,0x3c0001e,0x3c0f800,0x1e0003,0xc0f0001e,0x78000f0,0x3c000780,0x780000,
3574 0x3c00000,0x1e000000,0xf0000f00,0xf003c00,0x3c078003,0xe03c001f,0x1e000f8,0xf0007c0,0x78003e00,0x1e,0xf7803c,0x3c01e0,0x1e00f00,
3575 0xf007800,0x7803e00f,0x801e000f,0x80f803e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3576 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1,0xe0f0000f,0xff00001f,0x8000f87c,0x7800000,0x3c00,0x1e00,0x1c000,0x7fffff80,
3577 0x0,0x0,0x3,0xc0001e1f,0x83c0001e,0x1f,0x800000fe,0xf00780,0x7c0,0x7f001e00,0x3c0007,0xe03f003f,0x3fe0000,0x0,0x3fc00,0x0,
3578 0x7f,0x8001e000,0x781f00f0,0x1e00f003,0xc007e03c,0x1e0,0x3c03c0,0x1e00,0x3c00f,0xf81e0007,0x80007800,0x780,0x3f9f0000,0x7800001e,
3579 0xfe0f078,0x3c1e03c0,0x7807ff,0xff00f000,0x1e07fff8,0xfff8,0xf000,0xf0003c0,0xf81f003,0xc7bc7800,0xfe00000,0x78000003,0xe000003c,
3580 0x1e0,0x1e0,0x0,0x0,0x0,0x1fffc01,0xe000780f,0x1e0,0x780f00,0x1e0003c,0x3c000,0xf0078007,0x80003c00,0xf000,0x7bf0000,0x1e0000f,
3581 0x3c0f01e,0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0xf8000,0x3c000,0x3c003c0,0x1f00f807,0x81f03c00,0x3fe0001e,0xf00000,0x7c00007c,
3582 0xf0,0x3e0,0x3ff801,0x80000000,0x7800000,0x3cfcf800,0x3,0xffff0000,0x0,0x18,0xc0,0x0,0x7c00,0x1fff00,0x700003,0xc00f0003,
3583 0xcfcf8000,0x3e0000f3,0xf3e0079f,0x9f000000,0xf000,0x1000,0x0,0x0,0x0,0x0,0x0,0x1f0,0x1,0xc00f0078,0xf03cfcf,0x800007c0,0x1e000,
3584 0x0,0x780001,0xe018001f,0xfff8001c,0xe00007,0x8000003c,0xf001,0xf0000000,0x6380000,0xc0000000,0xf81f003,0xfffffe00,0x303,
3585 0x87006000,0x0,0x1ffff,0xfe003ffe,0x7f00,0x0,0x3c003c0,0x3fe1c00,0x3f00000,0x7,0xffc00000,0xf8,0x1f0001ff,0xf0000fff,0x80007ffc,
3586 0xfc000,0x3c01e00,0x1e00f000,0xf0078007,0x803c003c,0x1e001e0,0xf001e07,0x8003c000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,
3587 0x7800000,0x3c000001,0xe000fff8,0x3c0f078,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0x3fc001e,0x1e03c0f0,0x3c0780,
3588 0x1e03c00,0xf01e000,0x78000780,0x1e0007,0x80f0fc00,0x3fff80,0x1fffc00,0xfffe000,0x7fff0003,0xfff8001f,0xffc0001e,0x3c0f000,
3589 0x1e0003,0xc0f0001e,0x78000f0,0x3c000780,0x780000,0x3c00000,0x1e000000,0xf0001e00,0xf803c00,0x3c078001,0xe03c000f,0x1e00078,
3590 0xf0003c0,0x78001e07,0xfffffe1e,0x1e7803c,0x3c01e0,0x1e00f00,0xf007800,0x7801e00f,0x1e0007,0x807803c0,0x0,0x0,0x0,0x0,0x0,
3591 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x3,0xc0f00007,
3592 0xffc0007e,0xf03e,0x7800000,0x3c00,0x1e00,0x1c000,0x7fffff80,0x0,0x0,0x3,0xc0001e1f,0x83c0001e,0x3f,0x3e,0xf00780,0x3c0,0x7e001e00,
3593 0x7c000f,0x800f001f,0xffde0000,0x0,0x3e000,0x0,0xf,0x8003e000,0x781e0070,0x1e00f003,0xc001f03c,0x1e0,0x3c03c0,0x1e00,0x3c00f,
3594 0xf81e0007,0x80007800,0x780,0x3f1f0000,0x7800001e,0x7c0f078,0x1e1e03c0,0x7807ff,0xfc00f000,0x1e07fffe,0xffc,0xf000,0xf0003c0,
3595 0x781e003,0xc71c7800,0x1ff00000,0x78000003,0xe000003c,0x1e0,0x1e0,0x0,0x0,0x0,0xffffc01,0xe000780f,0x1e0,0x780fff,0xffe0003c,
3596 0x3c000,0xf0078007,0x80003c00,0xf000,0x7ff0000,0x1e0000f,0x3c0f01e,0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0x7f000,0x3c000,
3597 0x3c003c0,0xf00f007,0xc1f07c00,0x1fc0001f,0x1f00000,0xfc000ff8,0xf0,0x1ff,0xfffe07,0x80000000,0x7800000,0x7ffcfc00,0x0,0xf000000,
3598 0x0,0x18,0xc0,0x0,0x3e000,0x1ff80,0xe00003,0xc00f0007,0xffcfc000,0x3e0001ff,0xf3f00fff,0x9f800000,0x6000,0x0,0x0,0x7c000,
3599 0x0,0x0,0x0,0xfe,0x0,0xe00f007f,0xff07ffcf,0xc0000fc0,0x1e000,0x0,0x780001,0xe018001f,0xfff8001c,0xe00007,0x80000000,0xf800,
3600 0xf0000000,0x6380000,0xc0000000,0x1f03c000,0x1e00,0x303,0x83806000,0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xfe1c00,0x3f00000,0x0,
3601 0x0,0x3c,0xf801fff,0xfff8,0x7ffc0,0x1f8000,0x3c01e00,0x1e00f000,0xf0078007,0x803c003c,0x1e001e0,0xf003c07,0x8003c000,0x78000,
3602 0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x3c0f03c,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,
3603 0x78000f00,0x1f8001e,0x1e03c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78000780,0x1e000f,0x80f0ff00,0x1ffff80,0xffffc00,0x7fffe003,
3604 0xffff001f,0xfff800ff,0xffc007ff,0xffc0f000,0x1fffff,0xc0fffffe,0x7fffff0,0x3fffff80,0x780000,0x3c00000,0x1e000000,0xf0001e00,
3605 0x7803c00,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e07,0xfffffe1e,0x3c7803c,0x3c01e0,0x1e00f00,0xf007800,0x7801f01f,
3606 0x1e0007,0x807c07c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3607 0x0,0x0,0x0,0x0,0x780000,0x3,0xc0f00000,0xfff003f0,0x1f00f03e,0x7800000,0x3c00,0x1e00,0x1c000,0x7fffff80,0x0,0x7ff80000,0x3,
3608 0xc0001e0f,0x3c0001e,0x7e,0x1f,0x1e00780,0x3e0,0x7e000f00,0x78000f,0x7800f,0xff9e0000,0x0,0x3fc00,0x0,0x7f,0x8003c000,0x781e0070,
3609 0x3e00f803,0xc000f03c,0x1e0,0x3c03c0,0x1e00,0x3c00f,0xf81e0007,0x80007800,0x780,0x3e0f8000,0x7800001e,0x7c0f078,0x1e1e03c0,
3610 0x7807ff,0xf000f000,0x1e07807f,0xfe,0xf000,0xf0003c0,0x781e003,0xc71c7800,0x3ef00000,0x78000007,0xc000003c,0x1e0,0x1e0,0x0,
3611 0x0,0x0,0x1ffffc01,0xe000780f,0x1e0,0x780fff,0xffe0003c,0x3c000,0xf0078007,0x80003c00,0xf000,0x7ff0000,0x1e0000f,0x3c0f01e,
3612 0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0x7ff80,0x3c000,0x3c003c0,0xf00f003,0xc1f07800,0x1fc0000f,0x1e00000,0xf8000ff0,0xf0,
3613 0xff,0xffffff,0x80000000,0x3fffc000,0xfff9fe00,0x0,0xf000000,0x0,0x18,0xc0,0x0,0x1f0000,0x1fc0,0x1c00003,0xc00f000f,0xff9fe000,
3614 0x7c0003ff,0xe7f81fff,0x3fc00000,0x0,0x0,0x0,0xfe000,0x1ffffc0f,0xfffffc00,0x0,0xff,0xf0000000,0x700f007f,0xff0fff9f,0xe0000f80,
3615 0x1e000,0x0,0x780001,0xe018001f,0xfff8001c,0xe00fff,0xffc00000,0xf800,0xf0000000,0x6380000,0xc0ffff80,0x3e078000,0x1e00,0x7ff80303,
3616 0x83c06000,0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x3f00000,0x0,0x7f,0xff00001e,0x7c1fff0,0xfff80,0x7ffc00,0x3f0000,0x7c01f00,
3617 0x3e00f801,0xf007c00f,0x803e007c,0x1f003e0,0xf803c07,0x8003c000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,
3618 0xe0001e00,0x3c0f03c,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0x1f8001e,0x3c03c0f0,0x3c0780,0x1e03c00,0xf01e000,
3619 0x78000780,0x1e001f,0xf07f80,0x3ffff80,0x1ffffc00,0xffffe007,0xffff003f,0xfff801ff,0xffc03fff,0xffc0f000,0x1fffff,0xc0fffffe,
3620 0x7fffff0,0x3fffff80,0x780000,0x3c00000,0x1e000000,0xf0001e00,0x7803c00,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e07,
3621 0xfffffe1e,0x787803c,0x3c01e0,0x1e00f00,0xf007800,0x7800f01e,0x1e0007,0x803c0780,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3622 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1ff,0xffff8000,0x3ff80fc0,0x7fc1e01f,
3623 0x7800000,0x3c00,0x1e00,0x0,0x7fffff80,0x0,0x7ff80000,0x7,0x80001e00,0x3c0001e,0xfc,0xf,0x1e00780,0x1e0,0x7c000f00,0x78000f,
3624 0x78007,0xff1e0000,0x0,0x3ff00,0x0,0x1ff,0x8003c000,0x781e0070,0x3c007803,0xc000f03c,0x1e0,0x3c03c0,0x1e00,0x3c000,0x781e0007,
3625 0x80007800,0x780,0x3c07c000,0x7800001e,0x7c0f078,0xf1e03c0,0x780780,0xf000,0x1e07801f,0x3e,0xf000,0xf0003c0,0x781e003,0xcf1c7800,
3626 0x3cf80000,0x7800000f,0x8000003c,0xf0,0x1e0,0x0,0x0,0x0,0x3ffffc01,0xe000780f,0x1e0,0x780fff,0xffe0003c,0x3c000,0xf0078007,
3627 0x80003c00,0xf000,0x7ff8000,0x1e0000f,0x3c0f01e,0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0x3fff0,0x3c000,0x3c003c0,0xf81f003,
3628 0xc3b87800,0xf80000f,0x1e00001,0xf0000ff0,0xf0,0xff,0xf03fff,0x80000000,0x3fff8001,0xfff1ff00,0x0,0xf000000,0x0,0x18,0xc0,
3629 0x0,0x380000,0x7c0,0x3c00003,0xc00f001f,0xff1ff000,0xf80007ff,0xc7fc3ffe,0x3fe00000,0x0,0x0,0x0,0x1ff000,0x7ffffe1f,0xffffff00,
3630 0x0,0x7f,0xfe000000,0x780f007f,0xff1fff1f,0xf0001f00,0x1e000,0x0,0x780001,0xe0180000,0xf000001c,0xe00fff,0xffc00000,0x7c00,
3631 0xf0000000,0x31c0001,0x80ffff80,0x3e078000,0x1e00,0x7ff80183,0x81c0c000,0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x3f00000,
3632 0x0,0x7f,0xff00001e,0x7c7ff03,0xc03ff8fe,0x1ffc0f0,0x7e0000,0x7800f00,0x3c007801,0xe003c00f,0x1e0078,0xf003c0,0x7803c07,0x8003c000,
3633 0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x3c0f01e,0x3c078000,0xf03c0007,0x81e0003c,
3634 0xf0001e0,0x78000f00,0x3fc001e,0x7803c0f0,0x3c0780,0x1e03c00,0xf01e000,0x78000780,0x1e007f,0xf03fe0,0x7ffff80,0x3ffffc01,
3635 0xffffe00f,0xffff007f,0xfff803ff,0xffc07fff,0xffc0f000,0x1fffff,0xc0fffffe,0x7fffff0,0x3fffff80,0x780000,0x3c00000,0x1e000000,
3636 0xf0001e00,0x7803c00,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e07,0xfffffe1e,0x707803c,0x3c01e0,0x1e00f00,0xf007800,
3637 0x7800f01e,0x1e0007,0x803c0780,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3638 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1ff,0xffff8000,0x30f81f00,0xffe1e00f,0x87800000,0x3c00,0x1e00,0x0,0x1e0000,0x0,0x7ff80000,
3639 0x7,0x80001e00,0x3c0001e,0x1f8,0x7,0x83c00780,0x1e0,0x7c000f00,0xf8001e,0x3c001,0xfc1e0000,0x0,0x7fe0,0x0,0xffc,0x3c000,0x781e0070,
3640 0x3ffff803,0xc000783c,0x1e0,0x3c03c0,0x1e00,0x3c000,0x781e0007,0x80007800,0x780,0x3c07c000,0x7800001e,0x380f078,0xf1e03c0,
3641 0x780780,0xf000,0x1e07800f,0x8000001e,0xf000,0xf0003c0,0x3c3c003,0xcf1e7800,0x7c780000,0x7800000f,0x8000003c,0xf0,0x1e0,0x0,
3642 0x0,0x0,0x7f003c01,0xe000780f,0x1e0,0x780fff,0xffe0003c,0x3c000,0xf0078007,0x80003c00,0xf000,0x7f7c000,0x1e0000f,0x3c0f01e,
3643 0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0xfff8,0x3c000,0x3c003c0,0x781e003,0xc3b87800,0x1fc00007,0x83e00003,0xe0000ff8,0xf0,
3644 0x1ff,0xc007fe,0x0,0x7fff8001,0xffe3ff00,0x0,0x1e000000,0x0,0x18,0xc0,0x0,0x0,0x3c0,0x7800003,0xc00f001f,0xfe3ff000,0xf80007ff,
3645 0x8ffc3ffc,0x7fe00000,0x0,0x0,0x0,0x1ff000,0x0,0x0,0x0,0x1f,0xff000000,0x3c0f007f,0xff1ffe3f,0xf0003e00,0x1e000,0x0,0x780001,
3646 0xe0180000,0xf000001e,0x1e00fff,0xffc00000,0x3f00,0xf0000000,0x31c0001,0x80ffff80,0x1f03c000,0x1e00,0x7ff80183,0x81c0c000,
3647 0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x0,0x0,0x7f,0xff00003c,0xf87f007,0xc03f83ff,0x81fc01f0,0x7c0000,0x7ffff00,0x3ffff801,
3648 0xffffc00f,0xfffe007f,0xfff003ff,0xff807fff,0x8003c000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,
3649 0xe0001e00,0x3c0f01e,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0x7fe001e,0xf003c0f0,0x3c0780,0x1e03c00,0xf01e000,
3650 0x78000780,0x1ffffe,0xf00ff0,0xfe00780,0x7f003c03,0xf801e01f,0xc00f00fe,0x7807f0,0x3c0ffff,0xffc0f000,0x1fffff,0xc0fffffe,
3651 0x7fffff0,0x3fffff80,0x780000,0x3c00000,0x1e000000,0xf0001e00,0x7803c00,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e00,
3652 0x1e,0xf07803c,0x3c01e0,0x1e00f00,0xf007800,0x7800783e,0x1e0007,0x801e0f80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3653 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1ff,0xffff8000,0x307c0801,0xe1f1e00f,0x87000000,
3654 0x3c00,0x1e00,0x0,0x1e0000,0x0,0x7ff80000,0xf,0x1e00,0x3c0001e,0x3f0,0x7,0x83fffffc,0x1e0,0x7c000f00,0xf0001e,0x3c000,0x3e0000,
3655 0x0,0x1ffc,0x1fffff,0xf0007ff0,0x3c000,0x781e0070,0x7ffffc03,0xc000781e,0x1e0,0x7803c0,0x1e00,0x3c000,0x781e0007,0x80007800,
3656 0x780,0x3c03e000,0x7800001e,0xf078,0x79e03c0,0x780780,0xf000,0x1e078007,0x8000000f,0xf000,0xf0003c0,0x3c3c001,0xee0ef000,
3657 0xf87c0000,0x7800001f,0x3c,0x78,0x1e0,0x0,0x0,0x0,0x7c003c01,0xe000780f,0x1e0,0x780f00,0x3c,0x3c000,0xf0078007,0x80003c00,
3658 0xf000,0x7e3e000,0x1e0000f,0x3c0f01e,0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0x1ffc,0x3c000,0x3c003c0,0x781e003,0xe3b8f800,
3659 0x1fc00007,0x83c00007,0xc00000fc,0xf0,0x3e0,0x8001f8,0x0,0x7800000,0xffc7fe00,0x0,0x1e000000,0x0,0x18,0xc0,0x0,0x0,0x1e0,
3660 0xf000003,0xc00f000f,0xfc7fe001,0xf00003ff,0x1ff81ff8,0xffc00000,0x0,0x0,0x0,0x1ff000,0x0,0x0,0x0,0x3,0xff800000,0x1e0f0078,
3661 0xffc7f,0xe0007c00,0x1e000,0x0,0x780001,0xe0180000,0xf000000e,0x1c00007,0x80000000,0x1f81,0xe0000000,0x38e0003,0x80000000,
3662 0xf81f000,0x1e00,0x7ff801c3,0x80e1c000,0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x0,0x0,0x0,0xf8,0x1f070007,0xc03803ff,0xc1c001f0,
3663 0xf80000,0xfffff00,0x7ffff803,0xffffc01f,0xfffe00ff,0xfff007ff,0xffc07fff,0x8001e000,0x78000,0x3c0000,0x1e00000,0xf000000,
3664 0xf00000,0x7800000,0x3c000001,0xe0001e00,0x780f00f,0x3c078000,0xf03c0007,0x81e0003c,0xf0001e0,0x78000f00,0xf9f001e,0xf003c0f0,
3665 0x3c0780,0x1e03c00,0xf01e000,0x78000780,0x1ffffc,0xf003f8,0xf800780,0x7c003c03,0xe001e01f,0xf00f8,0x7807c0,0x3c0fc1e,0xf000,
3666 0x1e0000,0xf00000,0x7800000,0x3c000000,0x780000,0x3c00000,0x1e000000,0xf0001e00,0x7803c00,0x3c078001,0xe03c000f,0x1e00078,
3667 0xf0003c0,0x78001e00,0x1e,0x1e07803c,0x3c01e0,0x1e00f00,0xf007800,0x7800783c,0x1e0007,0x801e0f00,0x0,0x0,0x0,0x0,0x0,0x0,
3668 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ff,0xffff8000,0x303c0001,
3669 0xc071e007,0xcf000000,0x3c00,0x1e00,0x0,0x1e0000,0x0,0x0,0xf,0xf00,0x780001e,0x7e0,0x7,0x83fffffc,0x1e0,0x7c000f00,0x1f0001e,
3670 0x3c000,0x3c0000,0x0,0x3ff,0x801fffff,0xf003ff80,0x3c000,0x781e0070,0x7ffffc03,0xc000781e,0x1e0,0x7803c0,0x1e00,0x1e000,0x781e0007,
3671 0x80007800,0x780,0x3c01f000,0x7800001e,0xf078,0x79e03c0,0xf00780,0xf000,0x3e078007,0xc000000f,0xf000,0xf0003c0,0x3c3c001,
3672 0xee0ef000,0xf03e0000,0x7800003e,0x3c,0x78,0x1e0,0x0,0x0,0x0,0xf8003c01,0xe000780f,0x1e0,0x780f00,0x3c,0x3c000,0xf0078007,
3673 0x80003c00,0xf000,0x7c3e000,0x1e0000f,0x3c0f01e,0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0xfc,0x3c000,0x3c003c0,0x3c3e001,0xe7b8f000,
3674 0x3fe00007,0xc7c0000f,0xc000003e,0xf0,0x7c0,0x0,0x0,0x7c00000,0x7fcffc00,0x0,0x1e000000,0x0,0x18,0xc0,0x0,0x0,0x1e0,0x1e000003,
3675 0xc00f0007,0xfcffc003,0xe00001ff,0x3ff00ff9,0xff800000,0x0,0x0,0x0,0x1ff000,0x0,0x0,0x0,0x0,0x1f800000,0xf0f0078,0x7fcff,
3676 0xc000fc00,0x1e000,0x0,0x780001,0xe0180000,0xf000000f,0x87c00007,0x80000000,0xfe3,0xe0000000,0x18780c3,0x0,0x7c0f800,0x1e00,
3677 0xc3,0x80e18000,0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x0,0x0,0x0,0x1f0,0x3e00000f,0xc0000303,0xe00003f0,0xf00000,0xfffff80,
3678 0x7ffffc03,0xffffe01f,0xffff00ff,0xfff807ff,0xffc07fff,0x8001e000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,
3679 0x3c000001,0xe0001e00,0x780f00f,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e00,0x1f0f801f,0xe00780f0,0x3c0780,0x1e03c00,
3680 0xf01e000,0x78000780,0x1ffff8,0xf000f8,0x1f000780,0xf8003c07,0xc001e03e,0xf01f0,0x780f80,0x3c1f01e,0xf000,0x1e0000,0xf00000,
3681 0x7800000,0x3c000000,0x780000,0x3c00000,0x1e000000,0xf0001e00,0x7803c00,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e00,
3682 0x1e,0x3c07803c,0x3c01e0,0x1e00f00,0xf007800,0x78007c7c,0x1e0007,0x801f1f00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3683 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0x81c00000,0x303c0003,0x8039e003,0xef000000,
3684 0x3c00,0x1e00,0x0,0x1e0000,0x0,0x0,0x1e,0xf00,0x780001e,0xfc0,0x7,0x83fffffc,0x1e0,0x3c000f00,0x1e0001e,0x3c000,0x3c0000,
3685 0x0,0x7f,0xe01fffff,0xf00ffc00,0x3c000,0x781f00f0,0x7ffffc03,0xc000781e,0x1e0,0x7803c0,0x1e00,0x1e000,0x781e0007,0x80007800,
3686 0x780,0x3c01f000,0x7800001e,0xf078,0x7de01e0,0xf00780,0x7800,0x3c078003,0xc000000f,0xf000,0xf0003c0,0x3e7c001,0xee0ef001,
3687 0xf01e0000,0x7800003e,0x3c,0x3c,0x1e0,0x0,0x0,0x0,0xf0003c01,0xe000780f,0x1e0,0x780f00,0x3c,0x3c000,0xf0078007,0x80003c00,
3688 0xf000,0x781f000,0x1e0000f,0x3c0f01e,0x1e03c0,0xf00780,0x1e0f000,0x3c003c00,0x3e,0x3c000,0x3c003c0,0x3c3c001,0xe71cf000,0x7df00003,
3689 0xc780000f,0x8000003e,0xf0,0x780,0x0,0x0,0x3c00000,0x3fcff800,0x0,0x1e000000,0x0,0x18,0xc0,0x0,0x1f00fc,0x1e0,0x1e000001,
3690 0xe00f0003,0xfcff8003,0xe00000ff,0x3fe007f9,0xff000000,0x0,0x0,0x0,0x1ff000,0x0,0x0,0x0,0x0,0x7c00000,0xf0f0078,0x3fcff,0x8000f800,
3691 0x1e000,0x0,0x780001,0xe0180000,0xf000001f,0xffe00007,0x8000003c,0x7ff,0xc0000000,0x1c3ffc7,0x0,0x3e07c00,0x1e00,0xe3,0x80738000,
3692 0x0,0x78,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x0,0x0,0x0,0x3e0,0x7c00001d,0xc0000001,0xe0000770,0x1f00000,0xfffff80,0x7ffffc03,
3693 0xffffe01f,0xffff00ff,0xfff807ff,0xffc07fff,0x8001e000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,
3694 0xe0001e00,0x780f00f,0x3c03c001,0xe01e000f,0xf00078,0x78003c0,0x3c001e00,0x3e07c01f,0xc00780f0,0x3c0780,0x1e03c00,0xf01e000,
3695 0x78000780,0x1fffc0,0xf0007c,0x1e000780,0xf0003c07,0x8001e03c,0xf01e0,0x780f00,0x3c1e01e,0xf000,0x1e0000,0xf00000,0x7800000,
3696 0x3c000000,0x780000,0x3c00000,0x1e000000,0xf0001e00,0x7803c00,0x3c078001,0xe03c000f,0x1e00078,0xf0003c0,0x78001e00,0x1e,0x7807803c,
3697 0x3c01e0,0x1e00f00,0xf007800,0x78003c78,0x1e0007,0x800f1e00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3698 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0x83c00000,0x303c0003,0x8039e001,0xee000000,0x1e00,0x3c00,
3699 0x0,0x1e0000,0x0,0x0,0x1e,0xf00,0x780001e,0x1f80,0x7,0x83fffffc,0x1e0,0x3c000f00,0x1e0001e,0x3c000,0x3c0000,0x0,0x1f,0xfc1fffff,
3700 0xf07ff000,0x0,0x780f00f0,0x78003c03,0xc000781e,0x1e0,0xf803c0,0x1e00,0x1e000,0x781e0007,0x80007800,0x780,0x3c00f800,0x7800001e,
3701 0xf078,0x3de01e0,0xf00780,0x7800,0x3c078003,0xe000000f,0xf000,0xf0003c0,0x1e78001,0xfe0ff003,0xe01f0000,0x7800007c,0x3c,0x3c,
3702 0x1e0,0x0,0x0,0x0,0xf0007c01,0xe000f80f,0x800001e0,0xf80f00,0x3c,0x1e001,0xf0078007,0x80003c00,0xf000,0x780f800,0x1e0000f,
3703 0x3c0f01e,0x1e03c0,0x1f00780,0x3e0f000,0x7c003c00,0x1e,0x3c000,0x3c003c0,0x3c3c001,0xe71cf000,0xf8f80003,0xe780001f,0x1e,
3704 0xf0,0x780,0x0,0x0,0x3c00000,0x1ffff000,0x0,0x1e000000,0x0,0x18,0xc0,0x0,0x3bc1de,0x1e0,0xf000001,0xe00f0001,0xffff0007,0xc000007f,
3705 0xffc003ff,0xfe000000,0x0,0x0,0x0,0xfe000,0x0,0x0,0x0,0x0,0x3c00000,0x1e0f0078,0x1ffff,0x1f000,0x1e000,0x0,0x780000,0xf0180000,
3706 0xf000001f,0xfff00007,0x8000003c,0x1ff,0x80000000,0xe0ff0e,0x0,0x1f03e00,0x1e00,0x70,0x70000,0x0,0x78,0x0,0x0,0x0,0x3c003c0,
3707 0xe1c00,0x0,0x0,0x0,0x7c0,0xf8000019,0xc0000000,0xe0000670,0x1e00000,0xf000780,0x78003c03,0xc001e01e,0xf00f0,0x780780,0x3c0f807,
3708 0x8001e000,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0xf80f007,0xbc03c001,0xe01e000f,
3709 0xf00078,0x78003c0,0x3c001e00,0x7c03e00f,0x800780f0,0x3c0780,0x1e03c00,0xf01e000,0x78000780,0x1e0000,0xf0003c,0x1e000f80,
3710 0xf0007c07,0x8003e03c,0x1f01e0,0xf80f00,0x7c1e01e,0xf800,0x1e0000,0xf00000,0x7800000,0x3c000000,0x780000,0x3c00000,0x1e000000,
3711 0xf0001e00,0x7803c00,0x3c078003,0xe03c001f,0x1e000f8,0xf0007c0,0x78003e00,0x1f8001f,0xf00f803c,0x3c01e0,0x1e00f00,0xf007800,
3712 0x78003e78,0x1e000f,0x800f9e00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3713 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf,0x3c00000,0x303c0003,0x8039f001,0xfe000000,0x1e00,0x3c00,0x0,0x1e0000,0x0,0x0,0x3c,0xf00,
3714 0x780001e,0x3f00,0x7,0x80000780,0x3e0,0x3e000f00,0x3c0001e,0x3c000,0x7c0000,0x0,0x3,0xfe000000,0xff8000,0x0,0x3c0f81f0,0xf0001e03,
3715 0xc000780f,0x1e0,0xf003c0,0x1e00,0xf000,0x781e0007,0x80007800,0x780,0x3c007c00,0x7800001e,0xf078,0x3de01e0,0xf00780,0x7800,
3716 0x3c078001,0xe000000f,0xf000,0xf0003c0,0x1e78001,0xfc07f003,0xe00f0000,0x78000078,0x3c,0x1e,0x1e0,0x0,0x0,0x0,0xf0007c01,
3717 0xf000f007,0x800000f0,0xf80780,0x3c,0x1e001,0xf0078007,0x80003c00,0xf000,0x7807c00,0x1e0000f,0x3c0f01e,0x1e01e0,0x1e007c0,
3718 0x3c07800,0x7c003c00,0x1e,0x3c000,0x3c007c0,0x1e78001,0xe71df000,0xf8f80001,0xef80003e,0x1e,0xf0,0x780,0x0,0x0,0x3c00000,
3719 0xfffe000,0x0,0x3e000000,0x0,0x18,0x7fff,0xc0000000,0x60c306,0x1e0,0x7800001,0xe00f0000,0xfffe0007,0x8000003f,0xff8001ff,
3720 0xfc000000,0x0,0x0,0x0,0x7c000,0x0,0x0,0x0,0x0,0x3c00000,0x3c0f0078,0xfffe,0x3e000,0x1e000,0x0,0x780000,0xf0180000,0xf000003c,
3721 0xfcf80007,0x8000003c,0x7f,0x0,0x70001c,0x0,0xf81f00,0x0,0x38,0xe0000,0x0,0x0,0x0,0x0,0x0,0x3c003c0,0xe1c00,0x0,0x0,0x0,0xf81,
3722 0xf0000039,0xc0000000,0xe0000e70,0x1e00000,0x1e0003c0,0xf0001e07,0x8000f03c,0x781e0,0x3c0f00,0x1e0f007,0x8000f000,0x78000,
3723 0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0xf00f007,0xbc03c001,0xe01e000f,0xf00078,0x78003c0,
3724 0x3c001e00,0xf801f00f,0x800780f0,0x3c0780,0x1e03c00,0xf01e000,0x78000780,0x1e0000,0xf0003c,0x1e000f80,0xf0007c07,0x8003e03c,
3725 0x1f01e0,0xf80f00,0x7c1e01e,0x7800,0xf0000,0x780000,0x3c00000,0x1e000000,0x780000,0x3c00000,0x1e000000,0xf0000f00,0xf003c00,
3726 0x3c03c003,0xc01e001e,0xf000f0,0x7800780,0x3c003c00,0x1f8000f,0xe00f003c,0x7c01e0,0x3e00f00,0x1f007800,0xf8001ef8,0x1f000f,
3727 0x7be00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3728 0x0,0x0,0xf,0x3c00000,0x307c0003,0x8038f000,0xfc000000,0x1e00,0x3c00,0x0,0x1e0000,0xfc0000,0x0,0x7e00003c,0x780,0xf00001e,
3729 0x7e00,0xf,0x80000780,0x3c0,0x3e001e00,0x3c0001f,0x7c000,0x780007,0xe000003f,0x0,0xfe000000,0xfe0000,0x0,0x3c07c3f0,0xf0001e03,
3730 0xc000f80f,0x800001e0,0x1f003c0,0x1e00,0xf000,0x781e0007,0x80007800,0x4000f80,0x3c003c00,0x7800001e,0xf078,0x1fe01f0,0x1f00780,
3731 0x7c00,0x7c078001,0xf000001f,0xf000,0xf0003c0,0x1e78001,0xfc07f007,0xc00f8000,0x780000f8,0x3c,0x1e,0x1e0,0x0,0x0,0x0,0xf0007c01,
3732 0xf000f007,0xc00000f0,0xf80780,0x3c,0x1f003,0xf0078007,0x80003c00,0xf000,0x7807c00,0x1e0000f,0x3c0f01e,0x1e01e0,0x1e007c0,
3733 0x3c07800,0x7c003c00,0x1e,0x3c000,0x3c007c0,0x1e78000,0xfe0fe001,0xf07c0001,0xef00007c,0x1e,0xf0,0x780,0x0,0x0,0x1e00000,
3734 0x7cfc000,0xfc00000,0x3c00000f,0xc3f00000,0x18,0x7fff,0xc0000000,0x406303,0x3e0,0x3c00001,0xf00f0000,0x7cfc000f,0x8000001f,
3735 0x3f0000f9,0xf8000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0x780700f8,0x7cfc,0x7c000,0x1e000,0x0,0x780000,0xf8180000,
3736 0xf0000070,0x3c0007,0x8000003c,0x3f,0x80000000,0x3c0078,0x0,0x780f00,0x0,0x1e,0x3c0000,0x0,0x0,0x0,0x0,0x0,0x3e007c0,0xe1c00,
3737 0x0,0x0,0x0,0xf01,0xe0000071,0xc0000000,0xe0001c70,0x1e00000,0x1e0003c0,0xf0001e07,0x8000f03c,0x781e0,0x3c0f00,0x1e0f007,
3738 0x8000f800,0x78000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x1f00f003,0xfc03e003,0xe01f001f,
3739 0xf800f8,0x7c007c0,0x3e003e01,0xf000f80f,0xf00f0,0x3c0780,0x1e03c00,0xf01e000,0x78000780,0x1e0000,0xf0003c,0x1e000f80,0xf0007c07,
3740 0x8003e03c,0x1f01e0,0xf80f00,0x7c1e01e,0x7c00,0xf0000,0x780000,0x3c00000,0x1e000000,0x780000,0x3c00000,0x1e000000,0xf0000f00,
3741 0xf003c00,0x3c03c003,0xc01e001e,0xf000f0,0x7800780,0x3c003c00,0x1f8000f,0xc00f003c,0x7c01e0,0x3e00f00,0x1f007800,0xf8001ef0,
3742 0x1f000f,0x7bc00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3743 0x0,0x0,0x0,0x0,0x780000,0xf,0x3800040,0x30780003,0x8038f800,0x78000000,0x1e00,0x3c00,0x0,0x1e0000,0xfc0000,0x0,0x7e000078,
3744 0x780,0x1f00001e,0xfc00,0x20001f,0x780,0x80007c0,0x1f001e00,0x7c0000f,0x78000,0xf80007,0xe000003f,0x0,0x1e000000,0xf00000,
3745 0x3c000,0x3c03fff0,0xf0001e03,0xc001f007,0x800101e0,0x7e003c0,0x1e00,0x7800,0x781e0007,0x80007800,0x6000f00,0x3c003e00,0x7800001e,
3746 0xf078,0x1fe00f0,0x1e00780,0x3c00,0x78078000,0xf020001e,0xf000,0x7800780,0xff0001,0xfc07f00f,0x8007c000,0x780001f0,0x3c,0xf,
3747 0x1e0,0x0,0x0,0x0,0xf800fc01,0xf801f007,0xc00100f8,0x1f807c0,0x40003c,0xf807,0xf0078007,0x80003c00,0xf000,0x7803e00,0x1f0000f,
3748 0x3c0f01e,0x1e01f0,0x3e007e0,0x7c07c00,0xfc003c00,0x1e,0x3e000,0x3e007c0,0x1ff8000,0xfe0fe003,0xe03e0001,0xff0000fc,0x1e,
3749 0xf0,0x780,0x0,0x0,0x1f00080,0x3cf8000,0xfc00000,0x3c00001f,0x83f00000,0x18,0xc0,0x0,0xc06203,0x40003c0,0x1c00000,0xf80f0000,
3750 0x3cf8001f,0xf,0x3e000079,0xf0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0x700780fc,0x3cf8,0xfc000,0x1e000,0x0,0x780000,
3751 0x7c180000,0xf0000020,0x100007,0x8000003c,0xf,0x80000000,0x1f01f0,0x0,0x380700,0x0,0xf,0x80f80000,0x0,0x0,0x0,0x0,0x0,0x3e007c0,
3752 0xe1c00,0x0,0x0,0x0,0xe01,0xc0000071,0xc0000001,0xc0001c70,0x1e00040,0x1e0003c0,0xf0001e07,0x8000f03c,0x781e0,0x3c0f00,0x1e0f007,
3753 0x80007800,0x10078000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e00,0x7e00f003,0xfc01e003,0xc00f001e,
3754 0x7800f0,0x3c00780,0x1e003c00,0xe000700f,0x800f0078,0x7803c0,0x3c01e00,0x1e00f000,0xf0000780,0x1e0000,0xf0003c,0x1f001f80,
3755 0xf800fc07,0xc007e03e,0x3f01f0,0x1f80f80,0xfc1e01f,0x7c00,0x100f8000,0x807c0004,0x3e00020,0x1f000100,0x780000,0x3c00000,0x1e000000,
3756 0xf0000f80,0x1f003c00,0x3c03e007,0xc01f003e,0xf801f0,0x7c00f80,0x3e007c00,0x1f8000f,0x801f003e,0x7c01f0,0x3e00f80,0x1f007c00,
3757 0xf8001ff0,0x1f801f,0x7fc00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3758 0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0xf,0x7800078,0x31f80001,0xc070fc00,0xfc000000,0x1e00,0x7c00,0x0,0x1e0000,0xfc0000,0x0,0x7e000078,
3759 0x7c0,0x1f00001e,0x1f000,0x38003f,0x780,0xe000f80,0x1f803e00,0x780000f,0x800f8000,0x1f00007,0xe000003f,0x0,0x2000000,0x800000,
3760 0x3c000,0x3e01ff71,0xf0001f03,0xc007f007,0xc00301e0,0x1fc003c0,0x1e00,0x7c00,0x781e0007,0x80007800,0x7801f00,0x3c001f00,0x7800001e,
3761 0xf078,0xfe00f8,0x3e00780,0x3e00,0xf8078000,0xf838003e,0xf000,0x7c00f80,0xff0000,0xfc07e00f,0x8003c000,0x780001e0,0x3c,0xf,
3762 0x1e0,0x0,0x0,0x0,0xf801fc01,0xfc03e003,0xe003007c,0x3f803e0,0x1c0003c,0xfc0f,0xf0078007,0x80003c00,0xf000,0x7801f00,0xf8000f,
3763 0x3c0f01e,0x1e00f8,0x7c007f0,0xf803e01,0xfc003c00,0x8003e,0x1f000,0x1e00fc0,0xff0000,0xfe0fe007,0xc01f0000,0xfe0000f8,0x1e,
3764 0xf0,0x780,0x0,0x0,0xf80180,0x1cf0000,0x1f800000,0x3c00001f,0x83e00000,0x18,0xc0,0x0,0xc06203,0x70007c0,0xe00000,0x7e0f0000,
3765 0x1cf0001e,0x7,0x3c000039,0xe0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100,0x7c00000,0xe00780fc,0x2001cf0,0xf8000,0x1e000,0x0,
3766 0x780000,0x7e182000,0xf0000000,0x7,0x8000003c,0x7,0xc0000000,0x7ffc0,0x0,0x180300,0x0,0x3,0xffe00000,0x0,0x0,0x0,0x0,0x0,
3767 0x3f00fc0,0xe1c00,0x0,0x0,0x0,0xc01,0x800000e1,0xc0000003,0xc0003870,0x1f001c0,0x3e0003e1,0xf0001f0f,0x8000f87c,0x7c3e0,0x3e1f00,
3768 0x1f1e007,0x80007c00,0x30078000,0x3c0000,0x1e00000,0xf000000,0xf00000,0x7800000,0x3c000001,0xe0001e03,0xfc00f001,0xfc01f007,
3769 0xc00f803e,0x7c01f0,0x3e00f80,0x1f007c00,0x4000201f,0xc01f007c,0xf803e0,0x7c01f00,0x3e00f801,0xf0000780,0x1e0000,0xf0007c,
3770 0x1f003f80,0xf801fc07,0xc00fe03e,0x7f01f0,0x3f80f80,0x1fc1f03f,0x803e00,0x3007c003,0x803e001c,0x1f000e0,0xf800700,0x780000,
3771 0x3c00000,0x1e000000,0xf00007c0,0x3e003c00,0x3c01f00f,0x800f807c,0x7c03e0,0x3e01f00,0x1f00f800,0x1f80007,0xc03e001e,0xfc00f0,
3772 0x7e00780,0x3f003c01,0xf8000fe0,0x1fc03e,0x3f800,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3773 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1e,0x780007f,0xfff00001,0xe0f07f03,0xfe000000,0xf00,0x7800,0x0,
3774 0x1e0000,0xfc0000,0x0,0x7e0000f0,0x3f0,0x7e000fff,0xfc03ffff,0xf83f00fe,0x780,0xfc03f80,0xfc0fc00,0xf800007,0xe03f0018,0x7e00007,
3775 0xe000003f,0x0,0x0,0x0,0x3c000,0x1e007c71,0xe0000f03,0xffffe003,0xf01f01ff,0xff8003ff,0xffe01e00,0x3f01,0xf81e0007,0x803ffff0,
3776 0x7e03f00,0x3c000f00,0x7ffffe1e,0xf078,0xfe007e,0xfc00780,0x1f83,0xf0078000,0x783f00fe,0xf000,0x3f03f00,0xff0000,0xfc07e01f,
3777 0x3e000,0x780003ff,0xfffc003c,0x7,0x800001e0,0x0,0x0,0x0,0x7e07fc01,0xfe07e001,0xf80f007e,0x7f801f8,0xfc0003c,0x7ffe,0xf0078007,
3778 0x807ffffe,0xf000,0x7801f00,0xfff00f,0x3c0f01e,0x1e00fc,0xfc007f8,0x1f803f03,0xfc003c00,0xf80fc,0x1fff0,0x1f83fc0,0xff0000,
3779 0xfc07e007,0xc01f0000,0xfe0001ff,0xffe0001e,0xf0,0x780,0x0,0x0,0xfe0780,0xfe0000,0x1f000000,0x3c00001f,0x7c00e03,0x81c00018,
3780 0xc0,0x0,0x406203,0x7e01fc0,0x700000,0x7fffff80,0xfe0003f,0xffffc003,0xf800001f,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1f0,
3781 0x1f800001,0xc007c1fe,0x6000fe0,0x1ffffe,0x1e000,0x0,0x780000,0x3f98e03f,0xffff8000,0x7,0x8000003c,0x7,0xc0000000,0xfe00,
3782 0x0,0x80100,0x0,0x0,0x7f000000,0x0,0x1ffff,0xfe000000,0x0,0x0,0x3f83fe8,0xe1c00,0x0,0x0,0x0,0x801,0xc1,0xc0000007,0x80003070,
3783 0xfc0fc0,0x3c0001e1,0xe0000f0f,0x7878,0x3c3c0,0x1e1e00,0xf1e007,0xffc03f01,0xf007ffff,0xc03ffffe,0x1fffff0,0xfffff80,0x7fffe003,
3784 0xffff001f,0xfff800ff,0xffc01fff,0xf800f001,0xfc00fc1f,0x8007e0fc,0x3f07e0,0x1f83f00,0xfc1f800,0x1f,0xf07e003f,0x3f001f8,
3785 0x1f800fc0,0xfc007e07,0xe0000780,0x1e0000,0xf301f8,0xfc0ff80,0x7e07fc03,0xf03fe01f,0x81ff00fc,0xff807e0,0x7fc0f87f,0x81801f80,
3786 0xf003f01f,0x801f80fc,0xfc07e0,0x7e03f00,0xfffffc07,0xffffe03f,0xffff01ff,0xfff807e0,0x7e003c00,0x3c01f81f,0x800fc0fc,0x7e07e0,
3787 0x3f03f00,0x1f81f800,0x1f8000f,0xe07e001f,0x83fc00fc,0x1fe007e0,0xff003f07,0xf8000fe0,0x1fe07e,0x3f800,0x0,0x0,0x0,0x0,0x0,
3788 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1e,0x780007f,
3789 0xffe00000,0xffe03fff,0xdf000000,0xf00,0x7800,0x0,0x0,0xfc0000,0x0,0x7e0000f0,0x1ff,0xfc000fff,0xfc03ffff,0xf83ffffc,0x780,
3790 0xfffff00,0x7fff800,0xf000007,0xffff001f,0xffe00007,0xe000003f,0x0,0x0,0x0,0x3c000,0x1e000001,0xe0000f03,0xffffc001,0xffff01ff,
3791 0xff0003ff,0xffe01e00,0x1fff,0xf81e0007,0x803ffff0,0x7fffe00,0x3c000f80,0x7ffffe1e,0xf078,0xfe003f,0xff800780,0xfff,0xf0078000,
3792 0x7c3ffffc,0xf000,0x3ffff00,0xff0000,0xf803e01e,0x1e000,0x780003ff,0xfffc003c,0x7,0x800001e0,0x0,0x0,0x0,0x7fffbc01,0xffffc000,
3793 0xffff003f,0xfff800ff,0xffc0003c,0x3ffe,0xf0078007,0x807ffffe,0xf000,0x7800f80,0x7ff00f,0x3c0f01e,0x1e007f,0xff8007ff,0xff001fff,
3794 0xbc003c00,0xffffc,0x1fff0,0x1fffbc0,0xff0000,0x7c07c00f,0x800f8000,0x7e0001ff,0xffe0001e,0xf0,0x780,0x0,0x0,0x7fff80,0x7c0000,
3795 0x1f000000,0x3c00001e,0x7c00f07,0xc1e00018,0xc0,0x0,0x60e303,0x7ffff80,0x380000,0x3fffff80,0x7c0003f,0xffffc001,0xf000000f,
3796 0x80000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ff,0xff800003,0x8003ffff,0xfe0007c0,0x1ffffe,0x1e000,0x0,0x780000,0x1fffe03f,0xffff8000,
3797 0x7,0x8000003c,0x3,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ffff,0xfe000000,0x0,0x0,0x3fffdf8,0xe1c00,0x0,0x0,0x0,0x0,0x1c1,
3798 0xc000000f,0x7070,0x7fffc0,0x3c0001e1,0xe0000f0f,0x7878,0x3c3c0,0x1e1e00,0xf1e007,0xffc01fff,0xf007ffff,0xc03ffffe,0x1fffff0,
3799 0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01fff,0xf000f001,0xfc007fff,0x3fff8,0x1fffc0,0xfffe00,0x7fff000,0x3b,0xfffc003f,
3800 0xfff001ff,0xff800fff,0xfc007fff,0xe0000780,0x1e0000,0xf3fff8,0xffff780,0x7fffbc03,0xfffde01f,0xffef00ff,0xff7807ff,0xfbc0ffff,
3801 0xff800fff,0xf001ffff,0x800ffffc,0x7fffe0,0x3ffff00,0xfffffc07,0xffffe03f,0xffff01ff,0xfff803ff,0xfc003c00,0x3c00ffff,0x7fff8,
3802 0x3fffc0,0x1fffe00,0xffff000,0x1f,0xfffc001f,0xffbc00ff,0xfde007ff,0xef003fff,0x780007e0,0x1ffffc,0x1f800,0x0,0x0,0x0,0x0,
3803 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1e,0x700003f,
3804 0xffc00000,0x7fc01fff,0x9f800000,0xf80,0xf800,0x0,0x0,0xfc0000,0x0,0x7e0000f0,0xff,0xf8000fff,0xfc03ffff,0xf83ffff8,0x780,
3805 0xffffe00,0x7fff000,0xf000003,0xfffe001f,0xffc00007,0xe000003f,0x0,0x0,0x0,0x3c000,0xf000003,0xe0000f83,0xffff0000,0xffff01ff,
3806 0xfc0003ff,0xffe01e00,0xfff,0xf01e0007,0x803ffff0,0x7fffc00,0x3c0007c0,0x7ffffe1e,0xf078,0x7e003f,0xff000780,0x7ff,0xe0078000,
3807 0x3c3ffff8,0xf000,0x1fffe00,0x7e0000,0xf803e03e,0x1f000,0x780003ff,0xfffc003c,0x7,0x800001e0,0x0,0x0,0x0,0x3fff3c01,0xefff8000,
3808 0x7ffe001f,0xff78007f,0xff80003c,0x1ffc,0xf0078007,0x807ffffe,0xf000,0x78007c0,0x3ff00f,0x3c0f01e,0x1e003f,0xff0007bf,0xfe000fff,
3809 0xbc003c00,0xffff8,0xfff0,0xfff3c0,0x7e0000,0x7c07c01f,0x7c000,0x7c0001ff,0xffe0001e,0xf0,0x780,0x0,0x0,0x3fff80,0x380000,
3810 0x3e000000,0x7c00003e,0x7801f07,0xc1e00018,0xc0,0x0,0x39c1ce,0x7ffff00,0x1c0000,0xfffff80,0x380003f,0xffffc000,0xe0000007,
3811 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ff,0xff000007,0x1ffcf,0xfe000380,0x1ffffe,0x1e000,0x0,0x780000,0xfffe03f,0xffff8000,0x7,
3812 0x8000003c,0x3,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ffff,0xfe000000,0x0,0x0,0x3dffdf8,0xe1c00,0x0,0x0,0x0,0x0,0x381,
3813 0xc000001e,0xe070,0x7fff80,0x7c0001f3,0xe0000f9f,0x7cf8,0x3e7c0,0x1f3e00,0xfbe007,0xffc00fff,0xf007ffff,0xc03ffffe,0x1fffff0,
3814 0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01fff,0xc000f000,0xfc007ffe,0x3fff0,0x1fff80,0xfffc00,0x7ffe000,0x79,0xfff8001f,
3815 0xffe000ff,0xff0007ff,0xf8003fff,0xc0000780,0x1e0000,0xf3fff0,0x7ffe780,0x3fff3c01,0xfff9e00f,0xffcf007f,0xfe7803ff,0xf3c07ff3,
3816 0xff8007ff,0xe000ffff,0x7fff8,0x3fffc0,0x1fffe00,0xfffffc07,0xffffe03f,0xffff01ff,0xfff801ff,0xf8003c00,0x3c007ffe,0x3fff0,
3817 0x1fff80,0xfffc00,0x7ffe000,0x1d,0xfff8000f,0xff3c007f,0xf9e003ff,0xcf001ffe,0x780007c0,0x1efff8,0x1f000,0x0,0x0,0x0,0x0,
3818 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780000,0x1e,0xf000003,
3819 0xfe000000,0x1f000fff,0xfc00000,0x780,0xf000,0x0,0x0,0xf80000,0x0,0x7e0001e0,0x7f,0xf0000fff,0xfc03ffff,0xf81ffff0,0x780,
3820 0x7fff800,0x1ffe000,0x1f000000,0xfff8001f,0xff000007,0xe000003e,0x0,0x0,0x0,0x3c000,0xf800003,0xc0000783,0xfff80000,0x3ffe01ff,
3821 0xe00003ff,0xffe01e00,0x7ff,0xc01e0007,0x803ffff0,0x3fff800,0x3c0003c0,0x7ffffe1e,0xf078,0x7e000f,0xfe000780,0x3ff,0xc0078000,
3822 0x3e1fffe0,0xf000,0x7ff800,0x7e0000,0xf803e07c,0xf800,0x780003ff,0xfffc003c,0x3,0xc00001e0,0x0,0x0,0x0,0xffe3c01,0xe7ff0000,
3823 0x3ffc000f,0xfe78003f,0xfe00003c,0x7f0,0xf0078007,0x807ffffe,0xf000,0x78003e0,0xff00f,0x3c0f01e,0x1e001f,0xfe00079f,0xfc0007ff,
3824 0x3c003c00,0x7ffe0,0x1ff0,0x7fe3c0,0x7e0000,0x7c07c03e,0x3e000,0x7c0001ff,0xffe0001e,0xf0,0x780,0x0,0x0,0xfff00,0x100000,
3825 0x3e000000,0x7800003c,0xf800f07,0xc1e00018,0xc0,0x0,0x1f80fc,0x3fffc00,0xc0000,0x3ffff80,0x100003f,0xffffc000,0x40000002,
3826 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xfc000006,0xff87,0xfc000100,0x1ffffe,0x1e000,0x0,0x780000,0x3ffc03f,0xffff8000,0x7,
3827 0x8000003c,0x3,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ffff,0xfe000000,0x0,0x0,0x3dff9f8,0xe1c00,0x0,0x0,0x0,0x0,0x3ff,
3828 0xf800003c,0xfffe,0x1ffe00,0x780000f3,0xc000079e,0x3cf0,0x1e780,0xf3c00,0x7bc007,0xffc003ff,0xe007ffff,0xc03ffffe,0x1fffff0,
3829 0xfffff80,0x7fffe003,0xffff001f,0xfff800ff,0xffc01ffc,0xf000,0xfc001ffc,0xffe0,0x7ff00,0x3ff800,0x1ffc000,0x70,0xfff00007,
3830 0xff80003f,0xfc0001ff,0xe0000fff,0x780,0x1e0000,0xf3ffe0,0x1ffc780,0xffe3c00,0x7ff1e003,0xff8f001f,0xfc7800ff,0xe3c03fe1,
3831 0xff0003ff,0xc0007ffc,0x3ffe0,0x1fff00,0xfff800,0xfffffc07,0xffffe03f,0xffff01ff,0xfff800ff,0xf0003c00,0x3c003ffc,0x1ffe0,
3832 0xfff00,0x7ff800,0x3ffc000,0x38,0xfff00007,0xfe3c003f,0xf1e001ff,0x8f000ffc,0x780007c0,0x1e7ff0,0x1f000,0x0,0x0,0x0,0x0,0x0,
3833 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30000000,
3834 0x1fc,0x0,0x780,0xf000,0x0,0x0,0x1f80000,0x0,0x1e0,0x1f,0xc0000000,0x0,0x1ff80,0x0,0xffc000,0x7f8000,0x0,0x3fe00007,0xfc000000,
3835 0x7e,0x0,0x0,0x0,0x0,0x7c00000,0x0,0x0,0xff00000,0x0,0x0,0xfe,0x0,0x0,0x3fc000,0x0,0x0,0x0,0x3,0xf8000000,0xff,0xc0000000,
3836 0x1ff00,0x0,0x1fe000,0x0,0x0,0x0,0x0,0x3c,0x3,0xc00001e0,0x0,0x0,0x0,0x3f80000,0x1fc0000,0x7f00003,0xf8000007,0xf0000000,
3837 0x0,0xf0000000,0x0,0xf000,0x0,0x0,0x0,0x7,0xf8000787,0xf00001fc,0x3c000000,0x7f80,0x0,0x1f8000,0x0,0x0,0x0,0x7c000000,0x1e,
3838 0xf0,0x780,0x0,0x0,0x3fc00,0x0,0x3c000000,0x7800003c,0xf000601,0xc00018,0xc0,0x0,0x0,0x3fe000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3839 0x0,0x0,0x0,0x0,0x0,0x0,0xf,0xf0000000,0x7e03,0xf0000000,0x0,0x0,0x0,0x0,0xfe0000,0x0,0x0,0x3c,0x2007,0x80000000,0x0,0x0,
3840 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c7e0f0,0xe1c00,0x0,0x3800000,0x0,0x0,0x3ff,0xf8000078,0xfffe,0x7f800,0x0,0x0,0x0,0x0,
3841 0x0,0x0,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7f0,0x3f80,0x1fc00,0xfe000,0x7f0000,0x70,0x3fc00001,0xfe00000f,0xf000007f,
3842 0x800003fc,0x0,0x0,0xff00,0x7f0000,0x3f80000,0x1fc00000,0xfe000007,0xf000003f,0x80001f80,0xfc00007f,0xfe0,0x7f00,0x3f800,
3843 0x1fc000,0x0,0x0,0x0,0x3f,0xc0000000,0xff0,0x7f80,0x3fc00,0x1fe000,0xff0000,0x78,0x3fc00001,0xf800000f,0xc000007e,0x3f0,0x7c0,
3844 0x1e1fc0,0x1f000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3845 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30000000,0x0,0x0,0x3c0,0x1e000,0x0,0x0,0x1f00000,0x0,0x3c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3846 0x0,0x0,0x7c,0x0,0x0,0x0,0x0,0x3e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0xe0000000,0x0,0x0,0x0,
3847 0x0,0x0,0x0,0x0,0x3c,0x1,0xe00001e0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0000000,0x0,0xf000,0x0,0x0,0x0,0x0,0x780,0x0,0x3c000000,
3848 0x0,0x0,0x0,0x0,0x0,0x0,0x78000000,0x1e,0xf0,0x780,0x0,0x0,0x0,0x0,0x3c000000,0x78000078,0xf000000,0x18,0xc0,0x0,0x0,0x0,
3849 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x180000,0x0,0x0,0x3c,0x3c0f,0x80000000,
3850 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0xe1c00,0x0,0x1800000,0x0,0x0,0x3ff,0xf80000f0,0xfffe,0x0,0x0,0x0,0x0,
3851 0x0,0x0,0x0,0xc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3852 0x0,0x0,0xc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30,0x0,0x0,0x0,0x0,0x780,0x1e0000,0x1e000,0x0,0x0,0x0,
3853 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30000000,
3854 0x0,0x0,0x3c0,0x1e000,0x0,0x0,0x1f00000,0x0,0x3c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7c,0x0,0x0,0x0,0x0,0x1f80000,
3855 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0xf0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c,0x1,0xe00001e0,0x0,
3856 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xe0000000,0x0,0xf000,0x0,0x0,0x0,0x0,0x780,0x0,0x3c000000,0x0,0x0,0x0,0x0,0x0,0x0,0xf8000000,
3857 0x1f,0xf0,0xf80,0x0,0x0,0x0,0x0,0x78000000,0xf8000078,0x1e000000,0x8,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3858 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x180000,0x0,0x0,0x3c,0x3fff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3859 0x0,0x3c00000,0xe1c00,0x0,0x1c00000,0x0,0x0,0x1,0xc00001e0,0x70,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3860 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3861 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf80,0x1e0000,0x3e000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3862 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30000000,0x0,0x0,0x1e0,0x3c000,0x0,0x0,0x1f00000,
3863 0x0,0x780,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7c,0x0,0x0,0x0,0x0,0xfe0100,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3864 0x0,0x0,0x0,0x0,0xf8000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3f,0xf0000000,0xf0007fe0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0xe0000000,
3865 0x0,0xf000,0x0,0x0,0x0,0x0,0x780,0x0,0x3c000000,0x0,0x0,0x0,0x0,0x0,0x0,0xf0000000,0x1f,0x800000f0,0x1f80,0x0,0x0,0x0,0x0,
3866 0x78000000,0xf0000070,0x1c000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3867 0x0,0x0,0x0,0x0,0x180000,0x0,0x0,0x3c,0x3ffe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0xe1c00,0x0,0xe00000,
3868 0x0,0x0,0x1,0xc00003ff,0xe0000070,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3869 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3870 0x0,0x0,0x0,0xf00,0x1e0000,0x3c000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3871 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30000000,0x0,0x0,0x1e0,0x7c000,0x0,0x0,0x1e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3872 0x0,0x0,0x0,0x0,0x0,0x78,0x0,0x0,0x0,0x0,0x7fff80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x78000000,
3873 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3f,0xf0000000,0x7fe0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4003,0xe0000000,0x0,0x1f000,0x0,0x0,
3874 0x0,0x0,0x780,0x0,0x3c000000,0x0,0x0,0x0,0x0,0x0,0x1,0xf0000000,0xf,0xfc0000f0,0x3ff00,0x0,0x0,0x0,0x0,0x70000001,0xf00000e0,
3875 0x1c000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x180000,
3876 0x0,0x0,0x3c,0xff8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0xe1c00,0x0,0xe00000,0x0,0x0,0x1,0xc00003ff,
3877 0xe0000070,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3878 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1f00,0x1e0000,
3879 0x7c000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3880 0x0,0x0,0x0,0x0,0x30000000,0x0,0x0,0xf0,0x78000,0x0,0x0,0x3e00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf8,0x0,
3881 0x0,0x0,0x0,0x1fff80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3f,
3882 0xf0000000,0x7fe0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780f,0xc0000000,0x0,0x3e000,0x0,0x0,0x0,0x0,0x780,0x0,0x3c000000,0x0,
3883 0x0,0x0,0x0,0x0,0x3,0xe0000000,0xf,0xfc0000f0,0x3ff00,0x0,0x0,0x0,0x0,0xf0000103,0xe0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3884 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x180000,0x0,0x0,0x3c,0x0,0x0,0x0,0x0,0x0,0x0,
3885 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0x0,0x0,0x21e00000,0x0,0x0,0x1,0xc00003ff,0xe0000070,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10f,
3886 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10f,0x0,
3887 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3e00,0x1e0000,0xf8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3888 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30000000,0x0,0x0,
3889 0xf8,0xf8000,0x0,0x0,0x3c00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0,0x0,0x0,0x0,0x0,0x1fe00,0x0,0x0,0x0,0x0,
3890 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3f,0xf0000000,0x7fe0,0x0,0x0,0x0,0x0,0x0,0x0,
3891 0x0,0x0,0x7fff,0xc0000000,0x0,0x3ffe000,0x0,0x0,0x0,0x0,0x780,0x0,0x3c000000,0x0,0x0,0x0,0x0,0x0,0x7f,0xe0000000,0x7,0xfc0000f0,
3892 0x3fe00,0x0,0x0,0x0,0x0,0x600001ff,0xe0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3893 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x180000,0x0,0x0,0x3c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0x0,0x0,
3894 0x3fe00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3895 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1ff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3896 0x0,0x0,0x0,0x0,0x7fe00,0x1e0000,0x1ff8000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3897 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3898 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3899 0x0,0x0,0x0,0x0,0x1fffffe0,0x0,0x0,0x0,0x0,0x0,0x0,0x7fff,0x80000000,0x0,0x3ffc000,0x0,0x0,0x0,0x0,0x780,0x0,0x3c000000,0x0,
3900 0x0,0x0,0x0,0x0,0x7f,0xc0000000,0x0,0xfc0000f0,0x3f000,0x0,0x0,0x0,0x0,0x1ff,0xc0000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3901 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3902 0x0,0x0,0x0,0x0,0x0,0x3c00000,0x0,0x0,0x3fc00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1fe,0x0,0x0,0x0,0x0,0x0,
3903 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1fe,0x0,0x0,0x0,0x0,0x0,0x0,
3904 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7fc00,0x1e0000,0x1ff0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3905 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3906 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3907 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1fffffe0,0x0,0x0,0x0,0x0,0x0,0x0,0x3ffe,0x0,0x0,0x3ff8000,0x0,0x0,0x0,
3908 0x0,0x780,0x0,0x3c000000,0x0,0x0,0x0,0x0,0x0,0x7f,0x80000000,0x0,0xf0,0x0,0x0,0x0,0x0,0x0,0x1ff,0x80000000,0x0,0x0,0x0,0x0,
3909 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3910 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0x0,0x0,0x3f800000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1fc,0x0,
3911 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1fc,0x0,0x0,
3912 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7f800,0x1e0000,0x1fe0000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3913 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3914 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3915 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1fffffe0,0x0,0x0,0x0,0x0,0x0,0x0,0x7f8,0x0,0x0,0x3fe0000,
3916 0x0,0x0,0x0,0x0,0x780,0x0,0x3c000000,0x0,0x0,0x0,0x0,0x0,0x7e,0x0,0x0,0xf0,0x0,0x0,0x0,0x0,0x0,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,
3917 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3918 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3919 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3920 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7e000,0x1e0000,0x1f80000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3921 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3922 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3923 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1fffffe0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3924 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3925 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3926 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3927 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3928 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3929 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3930 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3931 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0,0x0,0x0,0x0,
3932 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3933 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3934 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
3935 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 };
3938 const unsigned char logo40x38[4576] = {
3939 177,200,200,200,3,123,123,0,36,200,200,200,1,123,123,0,2,255,255,0,1,189,189,189,1,0,0,0,34,200,200,200,
3940 1,123,123,0,4,255,255,0,1,189,189,189,1,0,0,0,1,123,123,123,32,200,200,200,1,123,123,0,5,255,255,0,1,0,0,
3941 0,2,123,123,123,30,200,200,200,1,123,123,0,6,255,255,0,1,189,189,189,1,0,0,0,2,123,123,123,29,200,200,200,
3942 1,123,123,0,7,255,255,0,1,0,0,0,2,123,123,123,28,200,200,200,1,123,123,0,8,255,255,0,1,189,189,189,1,0,0,0,
3943 2,123,123,123,27,200,200,200,1,123,123,0,9,255,255,0,1,0,0,0,2,123,123,123,26,200,200,200,1,123,123,0,10,255,
3944 255,0,1,189,189,189,1,0,0,0,2,123,123,123,25,200,200,200,1,123,123,0,3,255,255,0,1,189,189,189,3,0,0,0,1,189,
3945 189,189,3,255,255,0,1,0,0,0,2,123,123,123,24,200,200,200,1,123,123,0,4,255,255,0,5,0,0,0,3,255,255,0,1,189,
3946 189,189,1,0,0,0,2,123,123,123,23,200,200,200,1,123,123,0,4,255,255,0,5,0,0,0,4,255,255,0,1,0,0,0,2,123,123,123,
3947 22,200,200,200,1,123,123,0,5,255,255,0,5,0,0,0,4,255,255,0,1,189,189,189,1,0,0,0,2,123,123,123,21,200,200,200,
3948 1,123,123,0,5,255,255,0,5,0,0,0,5,255,255,0,1,0,0,0,2,123,123,123,20,200,200,200,1,123,123,0,6,255,255,0,5,0,0,
3949 0,5,255,255,0,1,189,189,189,1,0,0,0,2,123,123,123,19,200,200,200,1,123,123,0,6,255,255,0,1,123,123,0,3,0,0,0,1,
3950 123,123,0,6,255,255,0,1,0,0,0,2,123,123,123,18,200,200,200,1,123,123,0,7,255,255,0,1,189,189,189,3,0,0,0,1,189,
3951 189,189,6,255,255,0,1,189,189,189,1,0,0,0,2,123,123,123,17,200,200,200,1,123,123,0,8,255,255,0,3,0,0,0,8,255,255,
3952 0,1,0,0,0,2,123,123,123,16,200,200,200,1,123,123,0,9,255,255,0,1,123,123,0,1,0,0,0,1,123,123,0,8,255,255,0,1,189,
3953 189,189,1,0,0,0,2,123,123,123,15,200,200,200,1,123,123,0,9,255,255,0,1,189,189,189,1,0,0,0,1,189,189,189,9,255,255,
3954 0,1,0,0,0,2,123,123,123,14,200,200,200,1,123,123,0,11,255,255,0,1,0,0,0,10,255,255,0,1,189,189,189,1,0,0,0,2,123,
3955 123,123,13,200,200,200,1,123,123,0,23,255,255,0,1,0,0,0,2,123,123,123,12,200,200,200,1,123,123,0,11,255,255,0,1,189,
3956 189,189,2,0,0,0,1,189,189,189,9,255,255,0,1,189,189,189,1,0,0,0,2,123,123,123,11,200,200,200,1,123,123,0,11,255,255,
3957 0,4,0,0,0,10,255,255,0,1,0,0,0,2,123,123,123,10,200,200,200,1,123,123,0,12,255,255,0,4,0,0,0,10,255,255,0,1,189,189,
3958 189,1,0,0,0,2,123,123,123,9,200,200,200,1,123,123,0,12,255,255,0,1,189,189,189,2,0,0,0,1,189,189,189,11,255,255,0,1,
3959 0,0,0,2,123,123,123,9,200,200,200,1,123,123,0,27,255,255,0,1,0,0,0,3,123,123,123,8,200,200,200,1,123,123,0,26,255,
3960 255,0,1,189,189,189,1,0,0,0,3,123,123,123,9,200,200,200,1,123,123,0,24,255,255,0,1,189,189,189,1,0,0,0,4,123,123,
3961 123,10,200,200,200,1,123,123,0,24,0,0,0,5,123,123,123,12,200,200,200,27,123,123,123,14,200,200,200,25,123,123,123,86,
3962 200,200,200,91,49,124,118,124,71,32,124,95,49,56,114,52,82,121,0};
3970 static std::FILE *res = stderr;
3971 if (file) res = file;
3989 inline void warn(
const char *
const format, ...) {
3991 char message[16384] = { 0 };
3993 va_start(ap,format);
3994 cimg_vsnprintf(message,
sizeof(message),format,ap);
3996 #ifdef cimg_strict_warnings
3999 std::fprintf(
cimg::output(),
"\n%s[CImg] *** Warning ***%s%s",cimg::t_red,cimg::t_normal,message);
4013 inline int system(
const char *
const command,
const char *
const module_name=0) {
4015 PROCESS_INFORMATION pi;
4017 std::memset(&pi,0,
sizeof(PROCESS_INFORMATION));
4018 std::memset(&si,0,
sizeof(STARTUPINFO));
4019 GetStartupInfo(&si);
4021 si.wShowWindow = SW_HIDE;
4022 si.dwFlags |= SW_HIDE | STARTF_USESHOWWINDOW;
4023 const BOOL res = CreateProcess((LPCTSTR)module_name,(LPTSTR)command,0,0,FALSE,0,0,0,&si,&pi);
4025 WaitForSingleObject(pi.hProcess, INFINITE);
4026 CloseHandle(pi.hThread);
4027 CloseHandle(pi.hProcess);
4031 return std::system(command);
4032 return module_name?0:1;
4036 template<
typename T>
4043 template<
typename T>
4044 inline void swap(T& a, T& b) { T t = a; a = b; b = t; }
4047 template<
typename T1,
typename T2>
4048 inline void swap(T1& a1, T1& b1, T2& a2, T2& b2) {
4053 template<
typename T1,
typename T2,
typename T3>
4054 inline void swap(T1& a1, T1& b1, T2& a2, T2& b2, T3& a3, T3& b3) {
4059 template<
typename T1,
typename T2,
typename T3,
typename T4>
4060 inline void swap(T1& a1, T1& b1, T2& a2, T2& b2, T3& a3, T3& b3, T4& a4, T4& b4) {
4065 template<
typename T1,
typename T2,
typename T3,
typename T4,
typename T5>
4066 inline void swap(T1& a1, T1& b1, T2& a2, T2& b2, T3& a3, T3& b3, T4& a4, T4& b4, T5& a5, T5& b5) {
4071 template<
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6>
4072 inline void swap(T1& a1, T1& b1, T2& a2, T2& b2, T3& a3, T3& b3, T4& a4, T4& b4, T5& a5, T5& b5, T6& a6, T6& b6) {
4073 cimg::swap(a1,b1,a2,b2,a3,b3,a4,b4,a5,b5);
cimg::swap(a6,b6);
4077 template<
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6,
typename T7>
4078 inline void swap(T1& a1, T1& b1, T2& a2, T2& b2, T3& a3, T3& b3, T4& a4, T4& b4, T5& a5, T5& b5, T6& a6, T6& b6,
4080 cimg::swap(a1,b1,a2,b2,a3,b3,a4,b4,a5,b5,a6,b6);
cimg::swap(a7,b7);
4084 template<
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6,
typename T7,
typename T8>
4085 inline void swap(T1& a1, T1& b1, T2& a2, T2& b2, T3& a3, T3& b3, T4& a4, T4& b4, T5& a5, T5& b5, T6& a6, T6& b6,
4086 T7& a7, T7& b7, T8& a8, T8& b8) {
4087 cimg::swap(a1,b1,a2,b2,a3,b3,a4,b4,a5,b5,a6,b6,a7,b7);
cimg::swap(a8,b8);
4096 return ((
unsigned char*)&x)[0]?
false:
true;
4104 template<
typename T>
4106 if (size)
switch (
sizeof(T)) {
4108 case 2 : {
for (
unsigned short *ptr = (
unsigned short*)buffer+size; ptr>(
unsigned short*)buffer; ) {
4109 const unsigned short val = *(--ptr);
4110 *ptr = (
unsigned short)((val>>8)|((val<<8)));
4113 case 4 : {
for (
unsigned int *ptr = (
unsigned int*)buffer+size; ptr>(
unsigned int*)buffer; ) {
4114 const unsigned int val = *(--ptr);
4115 *ptr = (val>>24)|((val>>8)&0xff00)|((val<<8)&0xff0000)|(val<<24);
4118 default : {
for (T* ptr = buffer+size; ptr>buffer; ) {
4119 unsigned char *pb = (
unsigned char*)(--ptr), *pe = pb +
sizeof(T);
4120 for (
int i = 0; i<(int)
sizeof(T)/2; ++i)
swap(*(pb++),*(--pe));
4131 template<
typename T>
4138 inline unsigned int float2uint(
const float f) {
4140 std::memcpy(&tmp,&f,
sizeof(
float));
4141 if (tmp>=0)
return (
unsigned int)f;
4143 std::memcpy(&u,&f,
sizeof(
float));
4147 inline float uint2float(
const unsigned int u) {
4148 if (u<(1U<<19))
return (
float)u;
4150 const unsigned int v = u|(1U<<(8*
sizeof(
unsigned int)-1));
4151 std::memcpy(&f,&v,
sizeof(
float));
4161 struct timeval st_time;
4162 gettimeofday(&st_time,0);
4163 return (
unsigned long)(st_time.tv_usec/1000 + st_time.tv_sec*1000);
4166 GetSystemTime(&st_time);
4167 return (
unsigned long)(st_time.wMilliseconds + 1000*(st_time.wSecond + 60*(st_time.wMinute + 60*st_time.wHour)));
4174 inline unsigned long tictoc(
const bool is_tic) {
4175 static unsigned long t0 = 0;
4177 if (is_tic)
return (t0 = t);
4180 edays = (
unsigned int)(dt/86400000.0),
4181 ehours = (
unsigned int)((dt - edays*86400000.0)/3600000.0),
4182 emin = (
unsigned int)((dt - edays*86400000.0 - ehours*3600000.0)/60000.0),
4183 esec = (
unsigned int)((dt - edays*86400000.0 - ehours*3600000.0 - emin*60000.0)/1000.0),
4184 ems = (
unsigned int)(dt - edays*86400000.0 - ehours*3600000.0 - emin*60000.0 - esec*1000.0);
4185 if (!edays && !ehours && !emin && !esec)
4186 std::fprintf(
cimg::output(),
"%s[CImg] Elapsed time: %u ms%s\n",cimg::t_red,ems,cimg::t_normal);
4188 if (!edays && !ehours && !emin)
4189 std::fprintf(
cimg::output(),
"%s[CImg] Elapsed time: %u sec %u ms%s\n",cimg::t_red,esec,ems,cimg::t_normal);
4191 if (!edays && !ehours)
4192 std::fprintf(
cimg::output(),
"%s[CImg] Elapsed time: %u min %u sec %u ms%s\n",cimg::t_red,emin,esec,ems,cimg::t_normal);
4195 std::fprintf(
cimg::output(),
"%s[CImg] Elapsed time: %u hours %u min %u sec %u ms%s\n",cimg::t_red,ehours,emin,esec,ems,cimg::t_normal);
4197 std::fprintf(
cimg::output(),
"%s[CImg] Elapsed time: %u days %u hours %u min %u sec %u ms%s\n",cimg::t_red,edays,ehours,emin,esec,ems,cimg::t_normal);
4210 return cimg::tictoc(
true);
4218 return cimg::tictoc(
false);
4227 inline void sleep(
const unsigned int milliseconds) {
4230 tv.tv_sec = milliseconds/1000;
4231 tv.tv_nsec = (milliseconds%1000)*1000000;
4234 Sleep(milliseconds);
4238 inline unsigned int _wait(
const unsigned int milliseconds,
unsigned long& timer) {
4240 const unsigned long current_time =
cimg::time();
4241 if (current_time>=timer+milliseconds) { timer = current_time;
return 0; }
4242 const unsigned long time_diff = timer + milliseconds - current_time;
4243 timer = current_time + time_diff;
4245 return (
unsigned int)time_diff;
4255 inline unsigned int wait(
const unsigned int milliseconds) {
4256 static unsigned long timer = 0;
4258 return _wait(milliseconds,timer);
4268 inline unsigned int _rand(
const unsigned long seed=0,
const bool set_seed=
false) {
4269 static unsigned long next = 1;
4270 if (set_seed) next = seed;
4271 next = next*1103515245 + 12345;
4272 return (
unsigned int)((next>>16)&0x7FFF);
4275 inline void srand() {
4276 static bool is_first_time =
true;
4277 if (is_first_time) {
4280 cimg::_rand(t+(
unsigned long)getpid(),
true);
4282 cimg::_rand(t+(
unsigned long)_getpid(),
true);
4284 cimg::_rand(t,
true);
4286 is_first_time =
false;
4290 inline double rand() {
4292 return cimg::_rand()/32767.;
4298 inline void srand() {
4299 static bool is_first_time =
true;
4300 if (is_first_time) {
4301 const unsigned int t = (
unsigned int)
cimg::time();
4303 std::srand(t+(
unsigned int)getpid());
4305 std::srand(t+(
unsigned int)_getpid());
4309 is_first_time =
false;
4318 return (
double)std::rand()/RAND_MAX;
4338 }
while (w<=0 || w>=1.0);
4339 return x1*std::sqrt((-2*std::log(w))/w);
4345 inline unsigned int prand(
const double z) {
4346 if (z<=1.0e-10)
return 0;
4347 if (z>100)
return (
unsigned int)((std::sqrt(z) *
cimg::grand()) + z);
4349 const double y = std::exp(-z);
4350 for (
double s = 1.0; s>=y; ++k) s*=
cimg::rand();
4355 template<
typename T>
4356 inline T
rol(
const T a,
const unsigned int n=1) {
4357 return n?(T)((a<<n)|(a>>((
sizeof(T)<<3)-n))):a;
4360 inline float rol(
const float a,
const unsigned int n=1) {
4361 return (
float)
rol((
int)a,n);
4364 inline double rol(
const double a,
const unsigned int n=1) {
4365 return (
double)
rol((
long)a,n);
4369 template<
typename T>
4370 inline T
ror(
const T a,
const unsigned int n=1) {
4371 return n?(T)((a>>n)|(a<<((
sizeof(T)<<3)-n))):a;
4374 inline float ror(
const float a,
const unsigned int n=1) {
4375 return (
float)
ror((
int)a,n);
4378 inline double ror(
const double a,
const unsigned int n=1) {
4379 return (
double)
ror((
long)a,n);
4383 template<
typename T>
4387 inline bool abs(
const bool a) {
4390 inline unsigned char abs(
const unsigned char a) {
4393 inline unsigned short abs(
const unsigned short a) {
4396 inline unsigned int abs(
const unsigned int a) {
4399 inline unsigned long abs(
const unsigned long a) {
4402 inline double abs(
const double a) {
4403 return std::fabs(a);
4405 inline float abs(
const float a) {
4406 return (
float)std::fabs((
double)a);
4408 inline int abs(
const int a) {
4413 template<
typename T>
4420 return x>0?(int)(1+std::log10((
double)x)):1;
4424 template<
typename t1,
typename t2>
4425 inline typename cimg::superset<t1,t2>::type
min(
const t1& a,
const t2& b) {
4426 typedef typename cimg::superset<t1,t2>::type t1t2;
4427 return (t1t2)(a<=b?a:b);
4431 template<
typename t1,
typename t2,
typename t3>
4432 inline typename cimg::superset2<t1,t2,t3>::type
min(
const t1& a,
const t2& b,
const t3& c) {
4433 typedef typename cimg::superset2<t1,t2,t3>::type t1t2t3;
4438 template<
typename t1,
typename t2,
typename t3,
typename t4>
4439 inline typename cimg::superset3<t1,t2,t3,t4>::type
min(
const t1& a,
const t2& b,
const t3& c,
const t4& d) {
4440 typedef typename cimg::superset3<t1,t2,t3,t4>::type t1t2t3t4;
4445 template<
typename t1,
typename t2>
4446 inline typename cimg::superset<t1,t2>::type
max(
const t1& a,
const t2& b) {
4447 typedef typename cimg::superset<t1,t2>::type t1t2;
4448 return (t1t2)(a>=b?a:b);
4452 template<
typename t1,
typename t2,
typename t3>
4453 inline typename cimg::superset2<t1,t2,t3>::type
max(
const t1& a,
const t2& b,
const t3& c) {
4454 typedef typename cimg::superset2<t1,t2,t3>::type t1t2t3;
4459 template<
typename t1,
typename t2,
typename t3,
typename t4>
4460 inline typename cimg::superset3<t1,t2,t3,t4>::type
max(
const t1& a,
const t2& b,
const t3& c,
const t4& d) {
4461 typedef typename cimg::superset3<t1,t2,t3,t4>::type t1t2t3t4;
4466 template<
typename T>
4468 return (x<0)?(T)(-1):(x==0?(T)0:(T)1);
4472 template<
typename T>
4474 unsigned long i = 1;
4480 inline double sinc(
const double x) {
4481 return x?std::sin(x)/x:1;
4490 template<
typename T>
4491 inline T
mod(
const T& x,
const T& m) {
4492 const double dx = (double)x, dm = (
double)m;
4493 return (T)(dx - dm * std::floor(dx / dm));
4495 inline int mod(
const bool x,
const bool m) {
4498 inline int mod(
const char x,
const char m) {
4499 return x>=0?x%m:(x%m?m+x%m:0);
4501 inline int mod(
const short x,
const short m) {
4502 return x>=0?x%m:(x%m?m+x%m:0);
4504 inline int mod(
const int x,
const int m) {
4505 return x>=0?x%m:(x%m?m+x%m:0);
4507 inline int mod(
const long x,
const long m) {
4508 return x>=0?x%m:(x%m?m+x%m:0);
4510 inline int mod(
const unsigned char x,
const unsigned char m) {
4513 inline int mod(
const unsigned short x,
const unsigned short m) {
4516 inline int mod(
const unsigned int x,
const unsigned int m) {
4519 inline int mod(
const unsigned long x,
const unsigned long m) {
4529 template<
typename T>
4531 return a*b<=0?0:(a>0?(a<b?a:b):(a<b?b:a));
4535 inline double log2(
const double x) {
4536 static const double base = std::log(2.0);
4537 return std::log(x)/base;
4547 template<
typename T>
4548 inline T
round(
const T x,
const double y=1,
const int rounding_type=0) {
4550 const double sx = (double)x/y, floor = std::floor(sx), delta = sx - floor;
4551 return (T)(y*(rounding_type<0?floor:rounding_type>0?std::ceil(sx):delta<0.5?floor:std::ceil(sx)));
4554 inline double _pythagore(
double a,
double b) {
4556 if (absa>absb) {
const double tmp = absb/absa;
return absa*std::sqrt(1.0+tmp*tmp); }
4557 else {
const double tmp = absa/absb;
return absb==0?0:absb*std::sqrt(1.0+tmp*tmp); }
4562 return (
char)((x<'A'||x>
'Z')?x:x-
'A'+
'a');
4567 if (str)
for (
char *ptr = str; *ptr; ++ptr) *ptr =
uncase(*ptr);
4576 inline double atof(
const char *
const str) {
4577 double x = 0, y = 1;
4578 if (!str)
return 0;
else { std::sscanf(str,
"%lf/%lf",&x,&y);
return x/y; }
4589 inline int strncasecmp(
const char *
const str1,
const char *
const str2,
const int l) {
4591 if (!str1)
return str2?-1:0;
4592 const char *nstr1 = str1, *nstr2 = str2;
4593 int k, diff = 0;
for (k = 0; k<l && !(diff =
uncase(*nstr1)-
uncase(*nstr2)); ++k) { ++nstr1; ++nstr2; }
4604 inline int strcasecmp(
const char *
const str1,
const char *
const str2) {
4605 if (!str1)
return str2?-1:0;
4607 l1 = (
unsigned int)std::strlen(str1),
4608 l2 = (
unsigned int)std::strlen(str2);
4620 inline bool strpare(
char *
const str,
const char delimiter=
' ',
const bool is_symmetric=
false,
const bool is_iterative=
false) {
4621 if (!str)
return false;
4622 const int l = (int)std::strlen(str);
4624 if (is_symmetric)
for (p = 0, q = l-1; p<q && str[p]==delimiter && str[q]==delimiter; ) { --q; ++p;
if (!is_iterative)
break; }
4626 for (p = 0; p<l && str[p]==delimiter; ) { ++p;
if (!is_iterative)
break; }
4627 for (q = l-1; q>p && str[q]==delimiter; ) { --q;
if (!is_iterative)
break; }
4629 const int n = q - p + 1;
4630 if (n!=l) { std::memmove(str,str+p,n); str[n] = 0;
return true; }
4639 #define cimg_strescape(ci,co) case ci: *nd = co; ++ns; break;
4640 static unsigned int val = 0;
4641 for (
char *ns = str, *nd = str; *ns || (
bool)(*nd=0); ++nd)
if (*ns==
'\\')
switch (*(++ns)) {
4642 cimg_strescape(
'n',
'\n');
4643 cimg_strescape(
't',
'\t');
4644 cimg_strescape(
'v',
'\v');
4645 cimg_strescape(
'b',
'\b');
4646 cimg_strescape(
'r',
'\r');
4647 cimg_strescape(
'f',
'\f');
4648 cimg_strescape(
'a',
'\a');
4649 cimg_strescape(
'\\',
'\\');
4650 cimg_strescape(
'\?',
'\?');
4651 cimg_strescape(
'\'',
'\'');
4652 cimg_strescape(
'\"',
'\"');
4653 case 0 : *nd = 0;
break;
4654 case '0' :
case '1' :
case '2' :
case '3' :
case '4' :
case '5' :
case '6' :
case '7' :
4655 std::sscanf(ns,
"%o",&val);
while (*ns>=
'0' && *ns<=
'7') ++ns;
4658 std::sscanf(++ns,
"%x",&val);
while ((*ns>=
'0' && *ns<=
'7') || (*ns>=
'a' && *ns<=
'f') || (*ns>=
'A' && *ns<=
'F')) ++ns;
4660 default : *nd = *(ns++);
4661 }
else *nd = *(ns++);
4665 inline const char *strbuffersize(
const unsigned long size) {
4666 static char res[256] = { 0 };
4667 if (size<1024LU) cimg_snprintf(res,
sizeof(res),
"%lu byte%s",size,size>1?
"s":
"");
4668 else if (size<1024*1024LU) {
const float nsize = size/1024.0f; cimg_snprintf(res,
sizeof(res),
"%.1f Kio",nsize); }
4669 else if (size<1024*1024*1024LU) {
const float nsize = size/(1024*1024.0f); cimg_snprintf(res,
sizeof(res),
"%.1f Mio",nsize); }
4670 else {
const float nsize = size/(1024*1024*1024.0f); cimg_snprintf(res,
sizeof(res),
"%.1f Gio",nsize); }
4677 for (
const char *np = str; np>=str && (p=np); np = std::strchr(np,cimg_file_separator)+1) {}
4682 inline const char* filenamerand() {
4683 static char randomid[9] = { 0,0,0,0,0,0,0,0,0 };
4685 for (
unsigned int k = 0; k<8; ++k) {
4686 const int v = (int)std::rand()%3;
4687 randomid[k] = (char)(v==0?(
'0'+(std::rand()%10)):(v==1?(
'a'+(std::rand()%26)):(
'A'+(std::rand()%26))));
4693 inline void winformat_string(
char *
const str) {
4696 char *
const nstr =
new char[MAX_PATH];
4697 if (GetShortPathNameA(str,nstr,MAX_PATH)) std::strcpy(str,nstr);
4710 inline std::FILE *
fopen(
const char *
const path,
const char *
const mode) {
4717 if (*path==
'-' && (!path[1] || path[1]==
'.')) {
4718 res = (*mode==
'r')?stdin:stdout;
4720 if (*mode && mode[1]==
'b') {
4721 if (_setmode(_fileno(res),0x8000)==-1) res = 0;
4724 }
else res = std::fopen(path,mode);
4725 if (!res)
throw CImgIOException(
"cimg::fopen(): Failed to open file '%s' with mode '%s'.",
4738 if (!file)
warn(
"cimg::fclose(): Specified file is (null).");
4739 if (!file || file==stdin || file==stdout)
return 0;
4740 const int errn = std::fclose(file);
4741 if (errn!=0)
warn(
"cimg::fclose(): Error code %d returned during file closing.",
4752 inline const char*
temporary_path(
const char *
const user_path=0,
const bool reinit_path=
false) {
4753 #define _cimg_test_temporary_path(p) \
4754 if (!path_found) { \
4755 cimg_snprintf(st_path,1024,"%s",p); \
4756 cimg_snprintf(tmp,sizeof(tmp),"%s%c%s",st_path,cimg_file_separator,filetmp); \
4757 if ((file=std::fopen(tmp,"wb"))!=0) { cimg::fclose(file); std::remove(tmp); path_found = true; } \
4759 static char *st_path = 0;
4760 if (reinit_path) {
delete[] st_path; st_path = 0; }
4762 if (!st_path) st_path =
new char[1024];
4763 std::memset(st_path,0,1024);
4764 std::strncpy(st_path,user_path,1023);
4765 }
else if (!st_path) {
4766 st_path =
new char[1024];
4767 std::memset(st_path,0,1024);
4768 bool path_found =
false;
4769 char tmp[1024] = { 0 }, filetmp[512] = { 0 };
4770 std::FILE *file = 0;
4771 cimg_snprintf(filetmp,
sizeof(filetmp),
"%s.tmp",cimg::filenamerand());
4772 char *tmpPath = std::getenv(
"TMP");
4773 if (!tmpPath) { tmpPath = std::getenv(
"TEMP"); winformat_string(tmpPath); }
4774 if (tmpPath) _cimg_test_temporary_path(tmpPath);
4776 _cimg_test_temporary_path(
"C:\\WINNT\\Temp");
4777 _cimg_test_temporary_path(
"C:\\WINDOWS\\Temp");
4778 _cimg_test_temporary_path(
"C:\\Temp");
4779 _cimg_test_temporary_path(
"C:");
4780 _cimg_test_temporary_path(
"D:\\WINNT\\Temp");
4781 _cimg_test_temporary_path(
"D:\\WINDOWS\\Temp");
4782 _cimg_test_temporary_path(
"D:\\Temp");
4783 _cimg_test_temporary_path(
"D:");
4785 _cimg_test_temporary_path(
"/tmp");
4786 _cimg_test_temporary_path(
"/var/tmp");
4790 std::strncpy(tmp,filetmp,
sizeof(tmp)-1);
4791 if ((file=std::fopen(tmp,
"wb"))!=0) {
cimg::fclose(file); std::remove(tmp); path_found =
true; }
4794 throw CImgIOException(
"cimg::temporary_path(): Failed to locate path for writing temporary files.\n");
4806 inline const char* programfiles_path(
const char *
const user_path=0,
const bool reinit_path=
false) {
4807 static char *st_path = 0;
4808 if (reinit_path) {
delete[] st_path; st_path = 0; }
4810 if (!st_path) st_path =
new char[1024];
4811 std::memset(st_path,0,1024);
4812 std::strncpy(st_path,user_path,1023);
4813 }
else if (!st_path) {
4814 st_path =
new char[MAX_PATH];
4815 std::memset(st_path,0,MAX_PATH);
4817 #if !defined(__INTEL_COMPILER)
4818 if (!SHGetSpecialFolderPathA(0,st_path,0x0026,
false)) {
4819 const char *
const pfPath = std::getenv(
"PROGRAMFILES");
4820 if (pfPath) std::strncpy(st_path,pfPath,MAX_PATH-1);
4821 else std::strcpy(st_path,
"C:\\PROGRA~1");
4824 std::strcpy(st_path,
"C:\\PROGRA~1");
4837 inline const char*
imagemagick_path(
const char *
const user_path=0,
const bool reinit_path=
false) {
4838 static char *st_path = 0;
4839 if (reinit_path) {
delete[] st_path; st_path = 0; }
4841 if (!st_path) st_path =
new char[1024];
4842 std::memset(st_path,0,1024);
4843 std::strncpy(st_path,user_path,1023);
4844 }
else if (!st_path) {
4845 st_path =
new char[1024];
4846 std::memset(st_path,0,1024);
4847 bool path_found =
false;
4848 std::FILE *file = 0;
4850 const char *
const pf_path = programfiles_path();
4852 std::strcpy(st_path,
".\\convert.exe");
4853 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
4855 for (
int k = 32; k>=10 && !path_found; --k) {
4856 cimg_snprintf(st_path,
sizeof(st_path),
"%s\\IMAGEM~1.%.2d-\\convert.exe",pf_path,k);
4857 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
4859 for (
int k = 9; k>=0 && !path_found; --k) {
4860 cimg_snprintf(st_path,
sizeof(st_path),
"%s\\IMAGEM~1.%d-Q\\convert.exe",pf_path,k);
4861 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
4863 for (
int k = 32; k>=0 && !path_found; --k) {
4864 cimg_snprintf(st_path,
sizeof(st_path),
"%s\\IMAGEM~1.%d\\convert.exe",pf_path,k);
4865 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
4867 for (
int k = 32; k>=10 && !path_found; --k) {
4868 cimg_snprintf(st_path,
sizeof(st_path),
"%s\\IMAGEM~1.%.2d-\\VISUA~1\\BIN\\convert.exe",pf_path,k);
4869 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
4871 for (
int k = 9; k>=0 && !path_found; --k) {
4872 cimg_snprintf(st_path,
sizeof(st_path),
"%s\\IMAGEM~1.%d-Q\\VISUA~1\\BIN\\convert.exe",pf_path,k);
4873 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
4875 for (
int k = 32; k>=0 && !path_found; --k) {
4876 cimg_snprintf(st_path,
sizeof(st_path),
"%s\\IMAGEM~1.%d\\VISUA~1\\BIN\\convert.exe",pf_path,k);
4877 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
4879 for (
int k = 32; k>=10 && !path_found; --k) {
4880 cimg_snprintf(st_path,
sizeof(st_path),
"C:\\IMAGEM~1.%.2d-\\convert.exe",k);
4881 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
4883 for (
int k = 9; k>=0 && !path_found; --k) {
4884 cimg_snprintf(st_path,
sizeof(st_path),
"C:\\IMAGEM~1.%d-Q\\convert.exe",k);
4885 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
4887 for (
int k = 32; k>=0 && !path_found; --k) {
4888 cimg_snprintf(st_path,
sizeof(st_path),
"C:\\IMAGEM~1.%d\\convert.exe",k);
4889 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
4891 for (
int k = 32; k>=10 && !path_found; --k) {
4892 cimg_snprintf(st_path,
sizeof(st_path),
"C:\\IMAGEM~1.%.2d-\\VISUA~1\\BIN\\convert.exe",k);
4893 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
4895 for (
int k = 9; k>=0 && !path_found; --k) {
4896 cimg_snprintf(st_path,
sizeof(st_path),
"C:\\IMAGEM~1.%d-Q\\VISUA~1\\BIN\\convert.exe",k);
4897 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
4899 for (
int k = 32; k>=0 && !path_found; --k) {
4900 cimg_snprintf(st_path,
sizeof(st_path),
"C:\\IMAGEM~1.%d\\VISUA~1\\BIN\\convert.exe",k);
4901 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
4903 for (
int k = 32; k>=10 && !path_found; --k) {
4904 cimg_snprintf(st_path,
sizeof(st_path),
"D:\\IMAGEM~1.%.2d-\\convert.exe",k);
4905 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
4907 for (
int k = 9; k>=0 && !path_found; --k) {
4908 cimg_snprintf(st_path,
sizeof(st_path),
"D:\\IMAGEM~1.%d-Q\\convert.exe",k);
4909 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
4911 for (
int k = 32; k>=0 && !path_found; --k) {
4912 cimg_snprintf(st_path,
sizeof(st_path),
"D:\\IMAGEM~1.%d\\convert.exe",k);
4913 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
4915 for (
int k = 32; k>=10 && !path_found; --k) {
4916 cimg_snprintf(st_path,
sizeof(st_path),
"D:\\IMAGEM~1.%.2d-\\VISUA~1\\BIN\\convert.exe",k);
4917 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
4919 for (
int k = 9; k>=0 && !path_found; --k) {
4920 cimg_snprintf(st_path,
sizeof(st_path),
"D:\\IMAGEM~1.%d-Q\\VISUA~1\\BIN\\convert.exe",k);
4921 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
4923 for (
int k = 32; k>=0 && !path_found; --k) {
4924 cimg_snprintf(st_path,
sizeof(st_path),
"D:\\IMAGEM~1.%d\\VISUA~1\\BIN\\convert.exe",k);
4925 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
4927 if (!path_found) std::strcpy(st_path,
"convert.exe");
4930 std::strcpy(st_path,
"./convert");
4931 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
4933 if (!path_found) std::strcpy(st_path,
"convert");
4935 winformat_string(st_path);
4947 static char *st_path = 0;
4948 if (reinit_path) {
delete[] st_path; st_path = 0; }
4950 if (!st_path) st_path =
new char[1024];
4951 std::memset(st_path,0,1024);
4952 std::strncpy(st_path,user_path,1023);
4953 }
else if (!st_path) {
4954 st_path =
new char[1024];
4955 std::memset(st_path,0,1024);
4956 bool path_found =
false;
4957 std::FILE *file = 0;
4959 const char *
const pf_path = programfiles_path();
4961 std::strcpy(st_path,
".\\gm.exe");
4962 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
4964 for (
int k = 32; k>=10 && !path_found; --k) {
4965 cimg_snprintf(st_path,
sizeof(st_path),
"%s\\GRAPHI~1.%.2d-\\gm.exe",pf_path,k);
4966 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
4968 for (
int k = 9; k>=0 && !path_found; --k) {
4969 cimg_snprintf(st_path,
sizeof(st_path),
"%s\\GRAPHI~1.%d-Q\\gm.exe",pf_path,k);
4970 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
4972 for (
int k = 32; k>=0 && !path_found; --k) {
4973 cimg_snprintf(st_path,
sizeof(st_path),
"%s\\GRAPHI~1.%d\\gm.exe",pf_path,k);
4974 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
4976 for (
int k = 32; k>=10 && !path_found; --k) {
4977 cimg_snprintf(st_path,
sizeof(st_path),
"%s\\GRAPHI~1.%.2d-\\VISUA~1\\BIN\\gm.exe",pf_path,k);
4978 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
4980 for (
int k = 9; k>=0 && !path_found; --k) {
4981 cimg_snprintf(st_path,
sizeof(st_path),
"%s\\GRAPHI~1.%d-Q\\VISUA~1\\BIN\\gm.exe",pf_path,k);
4982 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
4984 for (
int k = 32; k>=0 && !path_found; --k) {
4985 cimg_snprintf(st_path,
sizeof(st_path),
"%s\\GRAPHI~1.%d\\VISUA~1\\BIN\\gm.exe",pf_path,k);
4986 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
4988 for (
int k = 32; k>=10 && !path_found; --k) {
4989 cimg_snprintf(st_path,
sizeof(st_path),
"C:\\GRAPHI~1.%.2d-\\gm.exe",k);
4990 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
4992 for (
int k = 9; k>=0 && !path_found; --k) {
4993 cimg_snprintf(st_path,
sizeof(st_path),
"C:\\GRAPHI~1.%d-Q\\gm.exe",k);
4994 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
4996 for (
int k = 32; k>=0 && !path_found; --k) {
4997 cimg_snprintf(st_path,
sizeof(st_path),
"C:\\GRAPHI~1.%d\\gm.exe",k);
4998 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
5000 for (
int k = 32; k>=10 && !path_found; --k) {
5001 cimg_snprintf(st_path,
sizeof(st_path),
"C:\\GRAPHI~1.%.2d-\\VISUA~1\\BIN\\gm.exe",k);
5002 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
5004 for (
int k = 9; k>=0 && !path_found; --k) {
5005 cimg_snprintf(st_path,
sizeof(st_path),
"C:\\GRAPHI~1.%d-Q\\VISUA~1\\BIN\\gm.exe",k);
5006 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
5008 for (
int k = 32; k>=0 && !path_found; --k) {
5009 cimg_snprintf(st_path,
sizeof(st_path),
"C:\\GRAPHI~1.%d\\VISUA~1\\BIN\\gm.exe",k);
5010 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
5012 for (
int k = 32; k>=10 && !path_found; --k) {
5013 cimg_snprintf(st_path,
sizeof(st_path),
"D:\\GRAPHI~1.%.2d-\\gm.exe",k);
5014 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
5016 for (
int k = 9; k>=0 && !path_found; --k) {
5017 cimg_snprintf(st_path,
sizeof(st_path),
"D:\\GRAPHI~1.%d-Q\\gm.exe",k);
5018 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
5020 for (
int k = 32; k>=0 && !path_found; --k) {
5021 cimg_snprintf(st_path,
sizeof(st_path),
"D:\\GRAPHI~1.%d\\gm.exe",k);
5022 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
5024 for (
int k = 32; k>=10 && !path_found; --k) {
5025 cimg_snprintf(st_path,
sizeof(st_path),
"D:\\GRAPHI~1.%.2d-\\VISUA~1\\BIN\\gm.exe",k);
5026 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
5028 for (
int k = 9; k>=0 && !path_found; --k) {
5029 cimg_snprintf(st_path,
sizeof(st_path),
"D:\\GRAPHI~1.%d-Q\\VISUA~1\\BIN\\gm.exe",k);
5030 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
5032 for (
int k = 32; k>=0 && !path_found; --k) {
5033 cimg_snprintf(st_path,
sizeof(st_path),
"D:\\GRAPHI~1.%d\\VISUA~1\\BIN\\gm.exe",k);
5034 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
5036 if (!path_found) std::strcpy(st_path,
"gm.exe");
5039 std::strcpy(st_path,
"./gm");
5040 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
5042 if (!path_found) std::strcpy(st_path,
"gm");
5044 winformat_string(st_path);
5055 inline const char*
medcon_path(
const char *
const user_path=0,
const bool reinit_path=
false) {
5056 static char *st_path = 0;
5057 if (reinit_path) {
delete[] st_path; st_path = 0; }
5059 if (!st_path) st_path =
new char[1024];
5060 std::memset(st_path,0,1024);
5061 std::strncpy(st_path,user_path,1023);
5062 }
else if (!st_path) {
5063 st_path =
new char[1024];
5064 std::memset(st_path,0,1024);
5065 bool path_found =
false;
5066 std::FILE *file = 0;
5068 const char *
const pf_path = programfiles_path();
5070 std::strcpy(st_path,
".\\medcon.exe");
5071 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
5074 cimg_snprintf(st_path,
sizeof(st_path),
"%s\\XMedCon\\bin\\medcon.bat",pf_path);
5075 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
5078 cimg_snprintf(st_path,
sizeof(st_path),
"%s\\XMedCon\\bin\\medcon.exe",pf_path);
5079 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
5081 if (!path_found) std::strcpy(st_path,
"medcon.exe");
5084 std::strcpy(st_path,
"./medcon");
5085 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
5087 if (!path_found) std::strcpy(st_path,
"medcon");
5089 winformat_string(st_path);
5100 inline const char *
ffmpeg_path(
const char *
const user_path=0,
const bool reinit_path=
false) {
5101 static char *st_path = 0;
5102 if (reinit_path) {
delete[] st_path; st_path = 0; }
5104 if (!st_path) st_path =
new char[1024];
5105 std::memset(st_path,0,1024);
5106 std::strncpy(st_path,user_path,1023);
5107 }
else if (!st_path) {
5108 st_path =
new char[1024];
5109 std::memset(st_path,0,1024);
5110 bool path_found =
false;
5111 std::FILE *file = 0;
5114 std::strcpy(st_path,
".\\ffmpeg.exe");
5115 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
5117 if (!path_found) std::strcpy(st_path,
"ffmpeg.exe");
5120 std::strcpy(st_path,
"./ffmpeg");
5121 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
5123 if (!path_found) std::strcpy(st_path,
"ffmpeg");
5125 winformat_string(st_path);
5136 inline const char *
gzip_path(
const char *
const user_path=0,
const bool reinit_path=
false) {
5137 static char *st_path = 0;
5138 if (reinit_path) {
delete[] st_path; st_path = 0; }
5140 if (!st_path) st_path =
new char[1024];
5141 std::memset(st_path,0,1024);
5142 std::strncpy(st_path,user_path,1023);
5143 }
else if (!st_path) {
5144 st_path =
new char[1024];
5145 std::memset(st_path,0,1024);
5146 bool path_found =
false;
5147 std::FILE *file = 0;
5150 std::strcpy(st_path,
".\\gzip.exe");
5151 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
5153 if (!path_found) std::strcpy(st_path,
"gzip.exe");
5156 std::strcpy(st_path,
"./gzip");
5157 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
5159 if (!path_found) std::strcpy(st_path,
"gzip");
5161 winformat_string(st_path);
5172 inline const char *
gunzip_path(
const char *
const user_path=0,
const bool reinit_path=
false) {
5173 static char *st_path = 0;
5174 if (reinit_path) {
delete[] st_path; st_path = 0; }
5176 if (!st_path) st_path =
new char[1024];
5177 std::memset(st_path,0,1024);
5178 std::strncpy(st_path,user_path,1023);
5179 }
else if (!st_path) {
5180 st_path =
new char[1024];
5181 std::memset(st_path,0,1024);
5182 bool path_found =
false;
5183 std::FILE *file = 0;
5186 std::strcpy(st_path,
".\\gunzip.exe");
5187 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
5189 if (!path_found) std::strcpy(st_path,
"gunzip.exe");
5192 std::strcpy(st_path,
"./gunzip");
5193 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
5195 if (!path_found) std::strcpy(st_path,
"gunzip");
5197 winformat_string(st_path);
5208 inline const char *
dcraw_path(
const char *
const user_path=0,
const bool reinit_path=
false) {
5209 static char *st_path = 0;
5210 if (reinit_path) {
delete[] st_path; st_path = 0; }
5212 if (!st_path) st_path =
new char[1024];
5213 std::memset(st_path,0,1024);
5214 std::strncpy(st_path,user_path,1023);
5215 }
else if (!st_path) {
5216 st_path =
new char[1024];
5217 std::memset(st_path,0,1024);
5218 bool path_found =
false;
5219 std::FILE *file = 0;
5222 std::strcpy(st_path,
".\\dcraw.exe");
5223 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
5225 if (!path_found) std::strcpy(st_path,
"dcraw.exe");
5228 std::strcpy(st_path,
"./dcraw");
5229 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
5231 if (!path_found) std::strcpy(st_path,
"dcraw");
5233 winformat_string(st_path);
5244 inline const char *
wget_path(
const char *
const user_path=0,
const bool reinit_path=
false) {
5245 static char *st_path = 0;
5246 if (reinit_path) {
delete[] st_path; st_path = 0; }
5248 if (!st_path) st_path =
new char[1024];
5249 std::memset(st_path,0,1024);
5250 std::strncpy(st_path,user_path,1023);
5251 }
else if (!st_path) {
5252 st_path =
new char[1024];
5253 std::memset(st_path,0,1024);
5254 bool path_found =
false;
5255 std::FILE *file = 0;
5258 std::strcpy(st_path,
".\\wget.exe");
5259 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
5261 if (!path_found) std::strcpy(st_path,
"wget.exe");
5264 std::strcpy(st_path,
"./wget");
5265 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
5267 if (!path_found) std::strcpy(st_path,
"wget");
5269 winformat_string(st_path);
5280 inline const char *
curl_path(
const char *
const user_path=0,
const bool reinit_path=
false) {
5281 static char *st_path = 0;
5282 if (reinit_path) {
delete[] st_path; st_path = 0; }
5284 if (!st_path) st_path =
new char[1024];
5285 std::memset(st_path,0,1024);
5286 std::strncpy(st_path,user_path,1023);
5287 }
else if (!st_path) {
5288 st_path =
new char[1024];
5289 std::memset(st_path,0,1024);
5290 bool path_found =
false;
5291 std::FILE *file = 0;
5294 std::strcpy(st_path,
".\\curl.exe");
5295 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
5297 if (!path_found) std::strcpy(st_path,
"curl.exe");
5300 std::strcpy(st_path,
"./curl");
5301 if ((file=std::fopen(st_path,
"r"))!=0) {
cimg::fclose(file); path_found =
true; }
5303 if (!path_found) std::strcpy(st_path,
"curl");
5305 winformat_string(st_path);
5312 if (!filename) {
if (body) *body = 0;
return 0; }
5313 const char *p = 0;
for (
const char *np = filename; np>=filename && (p=np); np = std::strchr(np,
'.')+1) {}
5315 if (body) std::strcpy(body,filename);
5316 return filename + std::strlen(filename);
5318 const unsigned int l = (
unsigned int)(p - filename - 1);
5319 if (body) { std::memcpy(body,filename,l); body[l] = 0; }
5324 inline char*
number_filename(
const char *
const filename,
const int number,
const unsigned int n,
char *
const str) {
5325 if (!filename) {
if (str) *str = 0;
return 0; }
5326 char format[1024] = { 0 }, body[1024] = { 0 };
5328 if (n>0) cimg_snprintf(format,
sizeof(format),
"%s_%%.%ud.%s",body,n,ext);
5329 else cimg_snprintf(format,
sizeof(format),
"%s_%%d.%s",body,ext);
5330 std::sprintf(str,format,number);
5340 inline const char *
file_type(std::FILE *
const file,
const char *
const filename) {
5341 if (!file && !filename)
5344 *
const _pnm =
"pnm",
5345 *
const _pfm =
"pfm",
5346 *
const _bmp =
"bmp",
5347 *
const _gif =
"gif",
5348 *
const _jpg =
"jpg",
5349 *
const _off =
"off",
5350 *
const _pan =
"pan",
5351 *
const _png =
"png",
5352 *
const _tif =
"tif",
5353 *
const _inr =
"inr",
5354 *
const _dcm =
"dcm";
5355 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"rb");
5356 const char *f_type = 0, *head;
5357 char header[2048] = { 0 },
item[1024] = { 0 };
5358 const unsigned char *
const uheader = (
unsigned char*)header;
5360 const unsigned int siz = (
unsigned int)std::fread(header,2048,1,nfile);
5363 if (!std::strncmp(header,
"OFF\n",4)) f_type = _off;
5364 else if (!std::strncmp(header,
"#INRIMAGE",9)) f_type = _inr;
5365 else if (!std::strncmp(header,
"PANDORE",7)) f_type = _pan;
5366 else if (!std::strncmp(header+128,
"DICM",4)) f_type = _dcm;
5367 else if (uheader[0]==0xFF && uheader[1]==0xD8 && uheader[2]==0xFF) f_type = _jpg;
5368 else if (header[0]==
'B' && header[1]==
'M') f_type = _bmp;
5369 else if (header[0]==
'G' && header[1]==
'I' && header[2]==
'F' && header[3]==
'8' && header[5]==
'a' &&
5370 (header[4]==
'7' || header[4]==
'9')) f_type = _gif;
5371 else if (uheader[0]==0x89 && uheader[1]==0x50 && uheader[2]==0x4E && uheader[3]==0x47 &&
5372 uheader[4]==0x0D && uheader[5]==0x0A && uheader[6]==0x1A && uheader[7]==0x0A) f_type = _png;
5373 else if ((uheader[0]==0x49 && uheader[1]==0x49) || (uheader[0]==0x4D && uheader[1]==0x4D)) f_type = _tif;
5376 while (head<header+siz && (err=std::sscanf(head,
"%1023[^\n]",
item))!=EOF && (*
item==
'#' || !err))
5377 head+=1+(err?std::strlen(
item):0);
5378 if (std::sscanf(
item,
" P%d",&err)==1) f_type = _pnm;
5379 else if (std::sscanf(
item,
" P%c",&cerr)==1 && (cerr==
'f' || cerr==
'F')) f_type = _pfm;
5392 template<
typename T>
5393 inline int fread(T *
const ptr,
const unsigned long nmemb, std::FILE *stream) {
5394 if (!ptr || nmemb<=0 || !stream)
5395 throw CImgArgumentException(
"cimg::fread(): Invalid reading request of %u %s%s from file %p to buffer %p.",
5398 const unsigned long wlimitT = 63*1024*1024, wlimit = wlimitT/
sizeof(T);
5399 unsigned long to_read = nmemb, al_read = 0, l_to_read = 0, l_al_read = 0;
5401 l_to_read = (to_read*
sizeof(T))<wlimitT?to_read:wlimit;
5402 l_al_read = (
unsigned long)std::fread((
void*)(ptr+al_read),
sizeof(T),l_to_read,stream);
5405 }
while (l_to_read==l_al_read && to_read>0);
5407 warn(
"cimg::fread(): Only %u/%u elements could be read from file.",
5420 template<
typename T>
5421 inline int fwrite(
const T *ptr,
const unsigned long nmemb, std::FILE *stream) {
5422 if (!ptr || !stream)
5423 throw CImgArgumentException(
"cimg::fwrite(): Invalid writing request of %u %s%s from buffer %p to file %p.",
5425 if (nmemb<=0)
return 0;
5426 const unsigned long wlimitT = 63*1024*1024, wlimit = wlimitT/
sizeof(T);
5427 unsigned long to_write = nmemb, al_write = 0, l_to_write = 0, l_al_write = 0;
5429 l_to_write = (to_write*
sizeof(T))<wlimitT?to_write:wlimit;
5430 l_al_write = (
unsigned long)std::fwrite((
void*)(ptr+al_write),
sizeof(T),l_to_write,stream);
5431 al_write+=l_al_write;
5432 to_write-=l_al_write;
5433 }
while (l_to_write==l_al_write && to_write>0);
5435 warn(
"cimg::fwrite(): Only %u/%u elements could be written in file.",
5451 if (!filename_local)
5452 throw CImgArgumentException(
"cimg::load_network_external(): Specified destination string is (null).");
5453 const char *
const _ext =
cimg::split_filename(filename), *
const ext = (*_ext && _ext>filename)?_ext-1:_ext;
5454 char command[1024] = { 0 };
5455 std::FILE *file = 0;
5456 *filename_local = 0;
5458 cimg_snprintf(filename_local,512,
"%s%c%s%s",
cimg::temporary_path(),cimg_file_separator,cimg::filenamerand(),ext);
5459 if ((file=std::fopen(filename_local,
"rb"))!=0)
cimg::fclose(file);
5463 cimg_snprintf(command,
sizeof(command),
"%s -f --silent --compressed -o \"%s\" \"%s\"",
cimg::curl_path(),filename_local,filename);
5465 if (!(file = std::fopen(filename_local,
"rb"))) {
5468 cimg_snprintf(command,
sizeof(command),
"%s -q -r -l 0 --no-cache -O \"%s\" \"%s\"",
cimg::wget_path(),filename_local,filename);
5470 if (!(file = std::fopen(filename_local,
"rb")))
5471 throw CImgIOException(
"cimg::load_network_external(): Failed to load file '%s' with external tools 'wget' or 'curl'.",filename);
5475 cimg_snprintf(command,
sizeof(command),
"%s.gz",filename_local);
5476 std::rename(filename_local,command);
5477 cimg_snprintf(command,
sizeof(command),
"%s --quiet %s.gz",
gunzip_path(),filename_local);
5479 file = std::fopen(filename_local,
"rb");
5481 cimg_snprintf(command,
sizeof(command),
"%s.gz",filename_local);
5482 std::rename(command,filename_local);
5483 file = std::fopen(filename_local,
"rb");
5486 std::fseek(file,0,SEEK_END);
5487 if (std::ftell(file)<=0)
5488 throw CImgIOException(
"cimg::load_network_external(): Failed to load file '%s' with external commands 'wget' or 'curl'.",filename);
5490 return filename_local;
5494 inline const char*
option(
const char *
const name,
const int argc,
const char *
const *
const argv,
5495 const char *
const defaut,
const char *
const usage,
const bool reset_static) {
5496 static bool first =
true, visu =
false;
5497 if (reset_static) { first =
true;
return 0; }
5498 const char *res = 0;
5501 visu =
cimg::option(
"-h",argc,argv,(
char*)0,(
char*)0,
false)!=0;
5502 visu |=
cimg::option(
"-help",argc,argv,(
char*)0,(
char*)0,
false)!=0;
5503 visu |=
cimg::option(
"--help",argc,argv,(
char*)0,(
char*)0,
false)!=0;
5505 if (!name && visu) {
5509 std::fprintf(
cimg::output(),
" (%s, %s)\n\n",__DATE__,__TIME__);
5511 if (defaut) std::fprintf(
cimg::output(),
"%s\n",defaut);
5516 while (k<argc && std::strcmp(argv[k],name)) ++k;
5517 res = (k++==argc?defaut:(k==argc?argv[--k]:argv[k]));
5518 }
else res = defaut;
5519 if (visu && usage) std::fprintf(
cimg::output(),
" %s%-16s%s %-24s %s%s%s\n",
5520 cimg::t_bold,name,cimg::t_normal,res?res:
"0",cimg::t_green,usage,cimg::t_normal);
5525 inline const char*
option(
const char *
const name,
const int argc,
const char *
const *
const argv,
5526 const char *
const defaut,
const char *
const usage=0) {
5527 return option(name,argc,argv,defaut,usage,
false);
5530 inline bool option(
const char *
const name,
const int argc,
const char *
const *
const argv,
5531 const bool defaut,
const char *
const usage=0) {
5532 const char *
const s =
cimg::option(name,argc,argv,(
char*)0);
5538 inline int option(
const char *
const name,
const int argc,
const char *
const *
const argv,
5539 const int defaut,
const char *
const usage=0) {
5540 const char *
const s =
cimg::option(name,argc,argv,(
char*)0);
5541 const int res = s?std::atoi(s):defaut;
5542 char tmp[256] = { 0 };
5543 cimg_snprintf(tmp,
sizeof(tmp),
"%d",res);
5548 inline char option(
const char *
const name,
const int argc,
const char *
const *
const argv,
5549 const char defaut,
const char *
const usage=0) {
5550 const char *
const s =
cimg::option(name,argc,argv,(
char*)0);
5551 const char res = s?*s:defaut;
5552 char tmp[8] = { 0 };
5558 inline float option(
const char *
const name,
const int argc,
const char *
const *
const argv,
5559 const float defaut,
const char *
const usage=0) {
5560 const char *
const s =
cimg::option(name,argc,argv,(
char*)0);
5561 const float res = s?(float)
cimg::atof(s):defaut;
5562 char tmp[256] = { 0 };
5563 cimg_snprintf(tmp,
sizeof(tmp),
"%g",res);
5568 inline double option(
const char *
const name,
const int argc,
const char *
const *
const argv,
5569 const double defaut,
const char *
const usage=0) {
5570 const char *
const s =
cimg::option(name,argc,argv,(
char*)0);
5572 char tmp[256] = { 0 };
5573 cimg_snprintf(tmp,
sizeof(tmp),
"%g",res);
5578 inline const char* argument(
const unsigned int nb,
const int argc,
const char *
const *
const argv,
const unsigned int nb_singles=0, ...) {
5579 for (
int k = 1, pos = 0; k<argc;) {
5580 const char *
const item = argv[k];
5581 bool option = (*item==
'-'), single_option =
false;
5584 va_start(ap,nb_singles);
5585 for (
unsigned int i = 0; i<nb_singles; ++i)
if (!
cimg::strcasecmp(item,va_arg(ap,
char*))) { single_option =
true;
break; }
5588 if (option) { ++k;
if (!single_option) ++k; }
5589 else {
if (pos++==(
int)nb)
return item;
else ++k; }
5599 char tmp[1024] = { 0 };
5600 std::fprintf(
cimg::output(),
"\n %s%sCImg Library %u.%u.%u%s, compiled %s ( %s ) with the following flags:\n\n",
5601 cimg::t_red,cimg::t_bold,cimg_version/100,(cimg_version/10)%10,cimg_version%10,
5602 cimg::t_normal,__DATE__,__TIME__);
5604 std::fprintf(
cimg::output(),
" > Operating System: %s%-13s%s %s('cimg_OS'=%d)%s\n",
5606 cimg_OS==1?
"Unix":(cimg_OS==2?
"Windows":
"Unknow"),
5607 cimg::t_normal,cimg::t_green,
5611 std::fprintf(
cimg::output(),
" > CPU endianness: %s%s Endian%s\n",
5616 std::fprintf(
cimg::output(),
" > Verbosity mode: %s%-13s%s %s('cimg_verbosity'=%d)%s\n",
5618 cimg_verbosity==0?
"Quiet":(cimg_verbosity==1?
"Console":(cimg_verbosity==2?
"Dialog":(cimg_verbosity==3?
"Console+Warnings":
"Dialog+Warnings"))),
5619 cimg::t_normal,cimg::t_green,
5623 std::fprintf(
cimg::output(),
" > Stricts warnings: %s%-13s%s %s('cimg_strict_warnings' %s)%s\n",
5625 #ifdef cimg_strict_warnings
5626 "Yes",cimg::t_normal,cimg::t_green,
"defined",
5628 "No",cimg::t_normal,cimg::t_green,
"undefined",
5632 std::fprintf(
cimg::output(),
" > Using VT100 messages: %s%-13s%s %s('cimg_use_vt100' %s)%s\n",
5634 #ifdef cimg_use_vt100
5635 "Yes",cimg::t_normal,cimg::t_green,
"defined",
5637 "No",cimg::t_normal,cimg::t_green,
"undefined",
5641 std::fprintf(
cimg::output(),
" > Display type: %s%-13s%s %s('cimg_display'=%d)%s\n",
5643 cimg_display==0?
"No display":cimg_display==1?
"X11":cimg_display==2?
"Windows GDI":
"Unknown",
5644 cimg::t_normal,cimg::t_green,
5649 std::fprintf(
cimg::output(),
" > Using XShm for X11: %s%-13s%s %s('cimg_use_xshm' %s)%s\n",
5651 #ifdef cimg_use_xshm
5652 "Yes",cimg::t_normal,cimg::t_green,
"defined",
5654 "No",cimg::t_normal,cimg::t_green,
"undefined",
5658 std::fprintf(
cimg::output(),
" > Using XRand for X11: %s%-13s%s %s('cimg_use_xrandr' %s)%s\n",
5660 #ifdef cimg_use_xrandr
5661 "Yes",cimg::t_normal,cimg::t_green,
"defined",
5663 "No",cimg::t_normal,cimg::t_green,
"undefined",
5667 std::fprintf(
cimg::output(),
" > Using OpenMP: %s%-13s%s %s('cimg_use_openmp' %s)%s\n",
5669 #ifdef cimg_use_openmp
5670 "Yes",cimg::t_normal,cimg::t_green,
"defined",
5672 "No",cimg::t_normal,cimg::t_green,
"undefined",
5675 std::fprintf(
cimg::output(),
" > Using PNG library: %s%-13s%s %s('cimg_use_png' %s)%s\n",
5678 "Yes",cimg::t_normal,cimg::t_green,
"defined",
5680 "No",cimg::t_normal,cimg::t_green,
"undefined",
5683 std::fprintf(
cimg::output(),
" > Using JPEG library: %s%-13s%s %s('cimg_use_jpeg' %s)%s\n",
5685 #ifdef cimg_use_jpeg
5686 "Yes",cimg::t_normal,cimg::t_green,
"defined",
5688 "No",cimg::t_normal,cimg::t_green,
"undefined",
5692 std::fprintf(
cimg::output(),
" > Using TIFF library: %s%-13s%s %s('cimg_use_tiff' %s)%s\n",
5694 #ifdef cimg_use_tiff
5695 "Yes",cimg::t_normal,cimg::t_green,
"defined",
5697 "No",cimg::t_normal,cimg::t_green,
"undefined",
5701 std::fprintf(
cimg::output(),
" > Using Magick++ library: %s%-13s%s %s('cimg_use_magick' %s)%s\n",
5703 #ifdef cimg_use_magick
5704 "Yes",cimg::t_normal,cimg::t_green,
"defined",
5706 "No",cimg::t_normal,cimg::t_green,
"undefined",
5710 std::fprintf(
cimg::output(),
" > Using FFTW3 library: %s%-13s%s %s('cimg_use_fftw3' %s)%s\n",
5712 #ifdef cimg_use_fftw3
5713 "Yes",cimg::t_normal,cimg::t_green,
"defined",
5715 "No",cimg::t_normal,cimg::t_green,
"undefined",
5719 std::fprintf(
cimg::output(),
" > Using LAPACK library: %s%-13s%s %s('cimg_use_lapack' %s)%s\n",
5721 #ifdef cimg_use_lapack
5722 "Yes",cimg::t_normal,cimg::t_green,
"defined",
5724 "No",cimg::t_normal,cimg::t_green,
"undefined",
5729 std::fprintf(
cimg::output(),
" > Path of ImageMagick: %s%-13s%s\n",
5735 std::fprintf(
cimg::output(),
" > Path of GraphicsMagick: %s%-13s%s\n",
5741 std::fprintf(
cimg::output(),
" > Path of 'medcon': %s%-13s%s\n",
5747 std::fprintf(
cimg::output(),
" > Temporary path: %s%-13s%s\n",
5756 #ifdef cimg_use_lapack
5757 template<
typename T>
5758 inline void getrf(
int &N, T *lapA,
int *IPIV,
int &INFO) {
5759 dgetrf_(&N,&N,lapA,&N,IPIV,&INFO);
5762 inline void getrf(
int &N,
float *lapA,
int *IPIV,
int &INFO) {
5763 sgetrf_(&N,&N,lapA,&N,IPIV,&INFO);
5766 template<
typename T>
5767 inline void getri(
int &N, T *lapA,
int *IPIV, T* WORK,
int &LWORK,
int &INFO) {
5768 dgetri_(&N,lapA,&N,IPIV,WORK,&LWORK,&INFO);
5771 inline void getri(
int &N,
float *lapA,
int *IPIV,
float* WORK,
int &LWORK,
int &INFO) {
5772 sgetri_(&N,lapA,&N,IPIV,WORK,&LWORK,&INFO);
5775 template<
typename T>
5776 inline void gesvd(
char &JOB,
int &M,
int &N, T *lapA,
int &MN,
5777 T *lapS, T *lapU, T *lapV, T *WORK,
int &LWORK,
int &INFO) {
5778 dgesvd_(&JOB,&JOB,&M,&N,lapA,&MN,lapS,lapU,&M,lapV,&N,WORK,&LWORK,&INFO);
5781 inline void gesvd(
char &JOB,
int &M,
int &N,
float *lapA,
int &MN,
5782 float *lapS,
float *lapU,
float *lapV,
float *WORK,
int &LWORK,
int &INFO) {
5783 sgesvd_(&JOB,&JOB,&M,&N,lapA,&MN,lapS,lapU,&M,lapV,&N,WORK,&LWORK,&INFO);
5786 template<
typename T>
5787 inline void getrs(
char &TRANS,
int &N, T *lapA,
int *IPIV, T *lapB,
int &INFO) {
5789 dgetrs_(&TRANS,&N,&one,lapA,&N,IPIV,lapB,&N,&INFO);
5792 inline void getrs(
char &TRANS,
int &N,
float *lapA,
int *IPIV,
float *lapB,
int &INFO) {
5794 sgetrs_(&TRANS,&N,&one,lapA,&N,IPIV,lapB,&N,&INFO);
5797 template<
typename T>
5798 inline void syev(
char &JOB,
char &UPLO,
int &N, T *lapA, T *lapW, T *WORK,
int &LWORK,
int &INFO) {
5799 dsyev_(&JOB,&UPLO,&N,lapA,&N,lapW,WORK,&LWORK,&INFO);
5802 inline void syev(
char &JOB,
char &UPLO,
int &N,
float *lapA,
float *lapW,
float *WORK,
int &LWORK,
int &INFO) {
5803 ssyev_(&JOB,&UPLO,&N,lapA,&N,lapW,WORK,&LWORK,&INFO);
5806 template<
typename T>
5807 inline void sgels(
char & TRANS,
int &M,
int &N,
int &NRHS, T* lapA,
int &LDA,
5808 T* lapB,
int &LDB, T* WORK,
int &LWORK,
int &INFO){
5809 dgels_(&TRANS, &M, &N, &NRHS, lapA, &LDA, lapB, &LDB, WORK, &LWORK, &INFO);
5812 inline void sgels(
char & TRANS,
int &M,
int &N,
int &NRHS,
float* lapA,
int &LDA,
5813 float* lapB,
int &LDB,
float* WORK,
int &LWORK,
int &INFO){
5814 sgels_(&TRANS, &M, &N, &NRHS, lapA, &LDA, lapB, &LDB, WORK, &LWORK, &INFO);
5831 #define _cimg_create_ext_operators(typ) \
5832 template<typename T> \
5833 inline CImg<typename cimg::superset<T,typ>::type> operator+(const typ val, const CImg<T>& img) { \
5836 template<typename T> \
5837 inline CImg<typename cimg::superset<T,typ>::type> operator-(const typ val, const CImg<T>& img) { \
5838 typedef typename cimg::superset<T,typ>::type Tt; \
5839 return CImg<Tt>(img._width,img._height,img._depth,img._spectrum,val)-=img; \
5841 template<typename T> \
5842 inline CImg<typename cimg::superset<T,typ>::type> operator*(const typ val, const CImg<T>& img) { \
5845 template<typename T> \
5846 inline CImg<typename cimg::superset<T,typ>::type> operator/(const typ val, const CImg<T>& img) { \
5847 return val*img.get_invert(); \
5849 template<typename T> \
5850 inline CImg<typename cimg::superset<T,typ>::type> operator&(const typ val, const CImg<T>& img) { \
5853 template<typename T> \
5854 inline CImg<typename cimg::superset<T,typ>::type> operator|(const typ val, const CImg<T>& img) { \
5857 template<typename T> \
5858 inline CImg<typename cimg::superset<T,typ>::type> operator^(const typ val, const CImg<T>& img) { \
5861 template<typename T> \
5862 inline bool operator==(const typ val, const CImg<T>& img) { \
5863 return img == val; \
5865 template<typename T> \
5866 inline bool operator!=(const typ val, const CImg<T>& img) { \
5867 return img != val; \
5870 _cimg_create_ext_operators(
bool)
5871 _cimg_create_ext_operators(
unsigned char)
5872 _cimg_create_ext_operators(
char)
5873 _cimg_create_ext_operators(
signed char)
5874 _cimg_create_ext_operators(
unsigned short)
5875 _cimg_create_ext_operators(
short)
5876 _cimg_create_ext_operators(
unsigned int)
5877 _cimg_create_ext_operators(
int)
5878 _cimg_create_ext_operators(
unsigned long)
5879 _cimg_create_ext_operators(
long)
5880 _cimg_create_ext_operators(
float)
5881 _cimg_create_ext_operators(
double)
5883 template<typename T>
5884 inline CImg<_cimg_Tfloat> operator+(const
char *const expression, const CImg<T>& img) {
5885 return img + expression;
5888 template<
typename T>
5889 inline CImg<_cimg_Tfloat> operator-(
const char *
const expression,
const CImg<T>& img) {
5890 return CImg<_cimg_Tfloat>(img._width,img._height,img._depth,img._spectrum,expression,
true)-=img;
5893 template<
typename T>
5894 inline CImg<_cimg_Tfloat> operator*(
const char *
const expression,
const CImg<T>& img) {
5895 return img*expression;
5898 template<
typename T>
5899 inline CImg<_cimg_Tfloat> operator/(
const char *
const expression,
const CImg<T>& img) {
5900 return expression*img.get_invert();
5903 template<
typename T>
5904 inline CImg<T> operator&(
const char *
const expression,
const CImg<T>& img) {
5905 return img & expression;
5908 template<
typename T>
5909 inline CImg<T> operator|(
const char *
const expression,
const CImg<T>& img) {
5910 return img | expression;
5913 template<
typename T>
5914 inline CImg<T> operator^(
const char *
const expression,
const CImg<T>& img) {
5915 return img ^ expression;
5918 template<
typename T>
5919 inline bool operator==(
const char *
const expression,
const CImg<T>& img) {
5920 return img == expression;
5923 template<
typename T>
5924 inline bool operator!=(
const char *
const expression,
const CImg<T>& img) {
5925 return img != expression;
5928 template<
typename T>
5929 inline CImg<_cimg_Tfloat>
sqr(
const CImg<T>& instance) {
5930 return instance.get_sqr();
5933 template<
typename T>
5934 inline CImg<_cimg_Tfloat> sqrt(
const CImg<T>& instance) {
5935 return instance.get_sqrt();
5938 template<
typename T>
5939 inline CImg<_cimg_Tfloat> exp(
const CImg<T>& instance) {
5940 return instance.get_exp();
5943 template<
typename T>
5944 inline CImg<_cimg_Tfloat> log(
const CImg<T>& instance) {
5945 return instance.get_log();
5948 template<
typename T>
5949 inline CImg<_cimg_Tfloat>
log2(
const CImg<T>& instance) {
5950 return instance.get_log2();
5953 template<
typename T>
5954 inline CImg<_cimg_Tfloat> log10(
const CImg<T>& instance) {
5955 return instance.get_log10();
5958 template<
typename T>
5959 inline CImg<_cimg_Tfloat>
abs(
const CImg<T>& instance) {
5960 return instance.get_abs();
5963 template<
typename T>
5964 inline CImg<_cimg_Tfloat>
sign(
const CImg<T>& instance) {
5965 return instance.get_sign();
5968 template<
typename T>
5969 inline CImg<_cimg_Tfloat> cos(
const CImg<T>& instance) {
5970 return instance.get_cos();
5973 template<
typename T>
5974 inline CImg<_cimg_Tfloat> sin(
const CImg<T>& instance) {
5975 return instance.get_sin();
5978 template<
typename T>
5979 inline CImg<_cimg_Tfloat>
sinc(
const CImg<T>& instance) {
5980 return instance.get_sinc();
5983 template<
typename T>
5984 inline CImg<_cimg_Tfloat> tan(
const CImg<T>& instance) {
5985 return instance.get_tan();
5988 template<
typename T>
5989 inline CImg<_cimg_Tfloat> acos(
const CImg<T>& instance) {
5990 return instance.get_acos();
5993 template<
typename T>
5994 inline CImg<_cimg_Tfloat> asin(
const CImg<T>& instance) {
5995 return instance.get_asin();
5998 template<
typename T>
5999 inline CImg<_cimg_Tfloat> atan(
const CImg<T>& instance) {
6000 return instance.get_atan();
6003 template<
typename T>
6004 inline CImg<_cimg_Tfloat> cosh(
const CImg<T>& instance) {
6005 return instance.get_cosh();
6008 template<
typename T>
6009 inline CImg<_cimg_Tfloat> sinh(
const CImg<T>& instance) {
6010 return instance.get_sinh();
6013 template<
typename T>
6014 inline CImg<_cimg_Tfloat> tanh(
const CImg<T>& instance) {
6015 return instance.get_tanh();
6018 template<
typename T>
6019 inline CImg<T> transpose(
const CImg<T>& instance) {
6020 return instance.get_transpose();
6023 template<
typename T>
6024 inline CImg<_cimg_Tfloat> invert(
const CImg<T>& instance) {
6025 return instance.get_invert();
6028 template<
typename T>
6029 inline CImg<_cimg_Tfloat> pseudoinvert(
const CImg<T>& instance) {
6030 return instance.get_pseudoinvert();
6055 unsigned long _timer, _fps_frames, _fps_timer;
6056 unsigned int _width, _height, _normalization;
6057 float _fps_fps, _min, _max;
6058 bool _is_fullscreen;
6060 volatile unsigned int _window_width, _window_height, _button, _keys[128], _released_keys[128];
6061 volatile int _window_x, _window_y, _mouse_x, _mouse_y, _wheel;
6062 volatile bool _is_closed, _is_resized, _is_moved, _is_event,
6063 _is_keyESC, _is_keyF1, _is_keyF2, _is_keyF3, _is_keyF4, _is_keyF5, _is_keyF6, _is_keyF7,
6064 _is_keyF8, _is_keyF9, _is_keyF10, _is_keyF11, _is_keyF12, _is_keyPAUSE, _is_key1, _is_key2,
6065 _is_key3, _is_key4, _is_key5, _is_key6, _is_key7, _is_key8, _is_key9, _is_key0,
6066 _is_keyBACKSPACE, _is_keyINSERT, _is_keyHOME, _is_keyPAGEUP, _is_keyTAB, _is_keyQ, _is_keyW, _is_keyE,
6067 _is_keyR, _is_keyT, _is_keyY, _is_keyU, _is_keyI, _is_keyO, _is_keyP, _is_keyDELETE,
6068 _is_keyEND, _is_keyPAGEDOWN, _is_keyCAPSLOCK, _is_keyA, _is_keyS, _is_keyD, _is_keyF, _is_keyG,
6069 _is_keyH, _is_keyJ, _is_keyK, _is_keyL, _is_keyENTER, _is_keySHIFTLEFT, _is_keyZ, _is_keyX,
6070 _is_keyC, _is_keyV, _is_keyB, _is_keyN, _is_keyM, _is_keySHIFTRIGHT, _is_keyARROWUP, _is_keyCTRLLEFT,
6071 _is_keyAPPLEFT, _is_keyALT, _is_keySPACE, _is_keyALTGR, _is_keyAPPRIGHT, _is_keyMENU, _is_keyCTRLRIGHT, _is_keyARROWLEFT,
6072 _is_keyARROWDOWN, _is_keyARROWRIGHT, _is_keyPAD0, _is_keyPAD1, _is_keyPAD2, _is_keyPAD3, _is_keyPAD4, _is_keyPAD5,
6073 _is_keyPAD6, _is_keyPAD7, _is_keyPAD8, _is_keyPAD9, _is_keyPADADD, _is_keyPADSUB, _is_keyPADMUL, _is_keyPADDIV;
6082 #ifdef cimgdisplay_plugin
6083 #include cimgdisplay_plugin
6085 #ifdef cimgdisplay_plugin1
6086 #include cimgdisplay_plugin1
6088 #ifdef cimgdisplay_plugin2
6089 #include cimgdisplay_plugin2
6091 #ifdef cimgdisplay_plugin3
6092 #include cimgdisplay_plugin3
6094 #ifdef cimgdisplay_plugin4
6095 #include cimgdisplay_plugin4
6097 #ifdef cimgdisplay_plugin5
6098 #include cimgdisplay_plugin5
6100 #ifdef cimgdisplay_plugin6
6101 #include cimgdisplay_plugin6
6103 #ifdef cimgdisplay_plugin7
6104 #include cimgdisplay_plugin7
6106 #ifdef cimgdisplay_plugin8
6107 #include cimgdisplay_plugin8
6137 _width(0),_height(0),_normalization(0),
6139 _is_fullscreen(false),
6141 _window_width(0),_window_height(0),_button(0),
6142 _window_x(0),_window_y(0),_mouse_x(-1),_mouse_y(-1),_wheel(0),
6143 _is_closed(true),_is_resized(false),_is_moved(false),_is_event(false) {
6159 _width(0),_height(0),_normalization(0),
6161 _is_fullscreen(false),
6163 _window_width(0),_window_height(0),_button(0),
6164 _window_x(0),_window_y(0),_mouse_x(-1),_mouse_y(-1),_wheel(0),
6165 _is_closed(true),_is_resized(false),_is_moved(false),_is_event(false) {
6177 template<
typename T>
6181 _width(0),_height(0),_normalization(0),
6183 _is_fullscreen(false),
6185 _window_width(0),_window_height(0),_button(0),
6186 _window_x(0),_window_y(0),_mouse_x(-1),_mouse_y(-1),_wheel(0),
6187 _is_closed(true),_is_resized(false),_is_moved(false),_is_event(false) {
6199 template<
typename T>
6203 _width(0),_height(0),_normalization(0),
6205 _is_fullscreen(false),
6207 _window_width(0),_window_height(0),_button(0),
6208 _window_x(0),_window_y(0),_mouse_x(-1),_mouse_y(-1),_wheel(0),
6209 _is_closed(true),_is_resized(false),_is_moved(false),_is_event(false) {
6219 _width(0),_height(0),_normalization(0),
6221 _is_fullscreen(false),
6223 _window_width(0),_window_height(0),_button(0),
6224 _window_x(0),_window_y(0),_mouse_x(-1),_mouse_y(-1),_wheel(0),
6225 _is_closed(true),_is_resized(false),_is_moved(false),_is_event(false) {
6231 static void _no_display_exception() {
6250 _no_display_exception();
6257 template<
typename T>
6261 _no_display_exception();
6268 template<
typename T>
6272 _no_display_exception();
6280 _no_display_exception();
6281 return assign(disp._width,disp._height);
6300 #define cimg_fitscreen(dx,dy,dz) CImgDisplay::_fitscreen(dx,dy,dz,128,-85,false),CImgDisplay::_fitscreen(dx,dy,dz,128,-85,true)
6301 static unsigned int _fitscreen(
const unsigned int dx,
const unsigned int dy,
const unsigned int dz,
6302 const int dmin,
const int dmax,
const bool return_y) {
6303 const unsigned int _nw = dx + (dz>1?dz:0), _nh = dy + (dz>1?dz:0);
6304 unsigned int nw = _nw?_nw:1, nh = _nh?_nh:1;
6307 mw = dmin<0?(
unsigned int)(sw*-dmin/100):(unsigned int)dmin,
6308 mh = dmin<0?(unsigned int)(sh*-dmin/100):(unsigned int)dmin,
6309 Mw = dmax<0?(unsigned int)(sw*-dmax/100):(unsigned int)dmax,
6310 Mh = dmax<0?(unsigned int)(sh*-dmax/100):(unsigned int)dmax;
6311 if (nw<mw) { nh = nh*mw/nw; nh+=(nh==0?1:0); nw = mw; }
6312 if (nh<mh) { nw = nw*mh/nh; nw+=(nw==0?1:0); nh = mh; }
6313 if (nw>Mw) { nh = nh*Mw/nw; nh+=(nh==0?1:0); nw = Mw; }
6314 if (nh>Mh) { nw = nw*Mh/nh; nw+=(nw==0?1:0); nh = Mh; }
6317 return return_y?nh:nw;
6331 template<
typename t>
6340 template<
typename t>
6372 return !(_width && _height);
6410 return _is_fullscreen;
6418 return _is_keyESC || _is_keyF1 || _is_keyF2 || _is_keyF3 ||
6419 _is_keyF4 || _is_keyF5 || _is_keyF6 || _is_keyF7 ||
6420 _is_keyF8 || _is_keyF9 || _is_keyF10 || _is_keyF11 ||
6421 _is_keyF12 || _is_keyPAUSE || _is_key1 || _is_key2 ||
6422 _is_key3 || _is_key4 || _is_key5 || _is_key6 ||
6423 _is_key7 || _is_key8 || _is_key9 || _is_key0 ||
6424 _is_keyBACKSPACE || _is_keyINSERT || _is_keyHOME ||
6425 _is_keyPAGEUP || _is_keyTAB || _is_keyQ || _is_keyW ||
6426 _is_keyE || _is_keyR || _is_keyT || _is_keyY ||
6427 _is_keyU || _is_keyI || _is_keyO || _is_keyP ||
6428 _is_keyDELETE || _is_keyEND || _is_keyPAGEDOWN ||
6429 _is_keyCAPSLOCK || _is_keyA || _is_keyS || _is_keyD ||
6430 _is_keyF || _is_keyG || _is_keyH || _is_keyJ ||
6431 _is_keyK || _is_keyL || _is_keyENTER ||
6432 _is_keySHIFTLEFT || _is_keyZ || _is_keyX || _is_keyC ||
6433 _is_keyV || _is_keyB || _is_keyN || _is_keyM ||
6434 _is_keySHIFTRIGHT || _is_keyARROWUP || _is_keyCTRLLEFT ||
6435 _is_keyAPPLEFT || _is_keyALT || _is_keySPACE || _is_keyALTGR ||
6436 _is_keyAPPRIGHT || _is_keyMENU || _is_keyCTRLRIGHT ||
6437 _is_keyARROWLEFT || _is_keyARROWDOWN || _is_keyARROWRIGHT ||
6438 _is_keyPAD0 || _is_keyPAD1 || _is_keyPAD2 ||
6439 _is_keyPAD3 || _is_keyPAD4 || _is_keyPAD5 ||
6440 _is_keyPAD6 || _is_keyPAD7 || _is_keyPAD8 ||
6441 _is_keyPAD9 || _is_keyPADADD || _is_keyPADSUB ||
6442 _is_keyPADMUL || _is_keyPADDIV;
6460 #define _cimg_iskey_test(k) if (keycode==cimg::key##k) return _is_key##k;
6461 _cimg_iskey_test(ESC); _cimg_iskey_test(F1); _cimg_iskey_test(F2); _cimg_iskey_test(F3);
6462 _cimg_iskey_test(F4); _cimg_iskey_test(F5); _cimg_iskey_test(F6); _cimg_iskey_test(F7);
6463 _cimg_iskey_test(F8); _cimg_iskey_test(F9); _cimg_iskey_test(F10); _cimg_iskey_test(F11);
6464 _cimg_iskey_test(F12); _cimg_iskey_test(PAUSE); _cimg_iskey_test(1); _cimg_iskey_test(2);
6465 _cimg_iskey_test(3); _cimg_iskey_test(4); _cimg_iskey_test(5); _cimg_iskey_test(6);
6466 _cimg_iskey_test(7); _cimg_iskey_test(8); _cimg_iskey_test(9); _cimg_iskey_test(0);
6467 _cimg_iskey_test(BACKSPACE); _cimg_iskey_test(INSERT); _cimg_iskey_test(HOME);
6468 _cimg_iskey_test(PAGEUP); _cimg_iskey_test(TAB); _cimg_iskey_test(Q); _cimg_iskey_test(W);
6469 _cimg_iskey_test(E); _cimg_iskey_test(R); _cimg_iskey_test(T); _cimg_iskey_test(Y);
6470 _cimg_iskey_test(U); _cimg_iskey_test(I); _cimg_iskey_test(O); _cimg_iskey_test(P);
6471 _cimg_iskey_test(DELETE); _cimg_iskey_test(END); _cimg_iskey_test(PAGEDOWN);
6472 _cimg_iskey_test(CAPSLOCK); _cimg_iskey_test(A); _cimg_iskey_test(S); _cimg_iskey_test(D);
6473 _cimg_iskey_test(F); _cimg_iskey_test(G); _cimg_iskey_test(H); _cimg_iskey_test(J);
6474 _cimg_iskey_test(K); _cimg_iskey_test(L); _cimg_iskey_test(ENTER);
6475 _cimg_iskey_test(SHIFTLEFT); _cimg_iskey_test(Z); _cimg_iskey_test(X); _cimg_iskey_test(C);
6476 _cimg_iskey_test(V); _cimg_iskey_test(B); _cimg_iskey_test(N); _cimg_iskey_test(M);
6477 _cimg_iskey_test(SHIFTRIGHT); _cimg_iskey_test(ARROWUP); _cimg_iskey_test(CTRLLEFT);
6478 _cimg_iskey_test(APPLEFT); _cimg_iskey_test(ALT); _cimg_iskey_test(SPACE); _cimg_iskey_test(ALTGR);
6479 _cimg_iskey_test(APPRIGHT); _cimg_iskey_test(MENU); _cimg_iskey_test(CTRLRIGHT);
6480 _cimg_iskey_test(ARROWLEFT); _cimg_iskey_test(ARROWDOWN); _cimg_iskey_test(ARROWRIGHT);
6481 _cimg_iskey_test(PAD0); _cimg_iskey_test(PAD1); _cimg_iskey_test(PAD2);
6482 _cimg_iskey_test(PAD3); _cimg_iskey_test(PAD4); _cimg_iskey_test(PAD5);
6483 _cimg_iskey_test(PAD6); _cimg_iskey_test(PAD7); _cimg_iskey_test(PAD8);
6484 _cimg_iskey_test(PAD9); _cimg_iskey_test(PADADD); _cimg_iskey_test(PADSUB);
6485 _cimg_iskey_test(PADMUL); _cimg_iskey_test(PADDIV);
6504 #define _cimg_iskey_test2(k) if (!cimg::strcasecmp(keycode,#k)) return _is_key##k;
6505 _cimg_iskey_test2(ESC); _cimg_iskey_test2(F1); _cimg_iskey_test2(F2); _cimg_iskey_test2(F3);
6506 _cimg_iskey_test2(F4); _cimg_iskey_test2(F5); _cimg_iskey_test2(F6); _cimg_iskey_test2(F7);
6507 _cimg_iskey_test2(F8); _cimg_iskey_test2(F9); _cimg_iskey_test2(F10); _cimg_iskey_test2(F11);
6508 _cimg_iskey_test2(F12); _cimg_iskey_test2(PAUSE); _cimg_iskey_test2(1); _cimg_iskey_test2(2);
6509 _cimg_iskey_test2(3); _cimg_iskey_test2(4); _cimg_iskey_test2(5); _cimg_iskey_test2(6);
6510 _cimg_iskey_test2(7); _cimg_iskey_test2(8); _cimg_iskey_test2(9); _cimg_iskey_test2(0);
6511 _cimg_iskey_test2(BACKSPACE); _cimg_iskey_test2(INSERT); _cimg_iskey_test2(HOME);
6512 _cimg_iskey_test2(PAGEUP); _cimg_iskey_test2(TAB); _cimg_iskey_test2(Q); _cimg_iskey_test2(W);
6513 _cimg_iskey_test2(E); _cimg_iskey_test2(R); _cimg_iskey_test2(T); _cimg_iskey_test2(Y);
6514 _cimg_iskey_test2(U); _cimg_iskey_test2(I); _cimg_iskey_test2(O); _cimg_iskey_test2(P);
6515 _cimg_iskey_test2(DELETE); _cimg_iskey_test2(END); _cimg_iskey_test2(PAGEDOWN);
6516 _cimg_iskey_test2(CAPSLOCK); _cimg_iskey_test2(A); _cimg_iskey_test2(S); _cimg_iskey_test2(D);
6517 _cimg_iskey_test2(F); _cimg_iskey_test2(G); _cimg_iskey_test2(H); _cimg_iskey_test2(J);
6518 _cimg_iskey_test2(K); _cimg_iskey_test2(L); _cimg_iskey_test2(ENTER);
6519 _cimg_iskey_test2(SHIFTLEFT); _cimg_iskey_test2(Z); _cimg_iskey_test2(X); _cimg_iskey_test2(C);
6520 _cimg_iskey_test2(V); _cimg_iskey_test2(B); _cimg_iskey_test2(N); _cimg_iskey_test2(M);
6521 _cimg_iskey_test2(SHIFTRIGHT); _cimg_iskey_test2(ARROWUP); _cimg_iskey_test2(CTRLLEFT);
6522 _cimg_iskey_test2(APPLEFT); _cimg_iskey_test2(ALT); _cimg_iskey_test2(SPACE); _cimg_iskey_test2(ALTGR);
6523 _cimg_iskey_test2(APPRIGHT); _cimg_iskey_test2(MENU); _cimg_iskey_test2(CTRLRIGHT);
6524 _cimg_iskey_test2(ARROWLEFT); _cimg_iskey_test2(ARROWDOWN); _cimg_iskey_test2(ARROWRIGHT);
6525 _cimg_iskey_test2(PAD0); _cimg_iskey_test2(PAD1); _cimg_iskey_test2(PAD2);
6526 _cimg_iskey_test2(PAD3); _cimg_iskey_test2(PAD4); _cimg_iskey_test2(PAD5);
6527 _cimg_iskey_test2(PAD6); _cimg_iskey_test2(PAD7); _cimg_iskey_test2(PAD8);
6528 _cimg_iskey_test2(PAD9); _cimg_iskey_test2(PADADD); _cimg_iskey_test2(PADSUB);
6529 _cimg_iskey_test2(PADMUL); _cimg_iskey_test2(PADDIV);
6550 bool is_key_sequence(
const unsigned int *
const keycodes_sequence,
const unsigned int length,
const bool remove_sequence=
false) {
6551 if (keycodes_sequence && length) {
6553 *
const ps_end = keycodes_sequence + length - 1,
6554 *
const pk_end = (
unsigned int*)_keys + 1 +
sizeof(_keys)/
sizeof(
unsigned int) - length,
6556 for (
unsigned int *pk = (
unsigned int*)_keys; pk<pk_end; ) {
6559 const unsigned int *ps = ps_end, *pk2 = pk;
6560 for (
unsigned int i = 1; i<length; ++i) res = (*(--ps)==*(pk2++));
6562 if (remove_sequence) std::memset((
void*)(pk-1),0,
sizeof(
unsigned int)*length);
6571 #define _cimg_iskey_def(k) \
6572 bool is_key##k() const { \
6573 return _is_key##k; \
6619 _no_display_exception();
6627 _no_display_exception();
6648 return (
int)_height;
6672 return _normalization;
6689 return (
int)_window_width;
6698 return (
int)_window_height;
6806 unsigned int key(
const unsigned int pos=0)
const {
6807 return pos<(
sizeof(_keys)/
sizeof(
unsigned int))?_keys[pos]:0;
6824 return pos<(
sizeof(_released_keys)/
sizeof(
unsigned int))?_released_keys[pos]:0;
6837 #define _cimg_keycode(k) if (!cimg::strcasecmp(keycode,#k)) return cimg::key##k;
6838 _cimg_keycode(ESC); _cimg_keycode(F1); _cimg_keycode(F2); _cimg_keycode(F3);
6839 _cimg_keycode(F4); _cimg_keycode(F5); _cimg_keycode(F6); _cimg_keycode(F7);
6840 _cimg_keycode(F8); _cimg_keycode(F9); _cimg_keycode(F10); _cimg_keycode(F11);
6841 _cimg_keycode(F12); _cimg_keycode(PAUSE); _cimg_keycode(1); _cimg_keycode(2);
6842 _cimg_keycode(3); _cimg_keycode(4); _cimg_keycode(5); _cimg_keycode(6);
6843 _cimg_keycode(7); _cimg_keycode(8); _cimg_keycode(9); _cimg_keycode(0);
6844 _cimg_keycode(BACKSPACE); _cimg_keycode(INSERT); _cimg_keycode(HOME);
6845 _cimg_keycode(PAGEUP); _cimg_keycode(TAB); _cimg_keycode(Q); _cimg_keycode(W);
6846 _cimg_keycode(E); _cimg_keycode(R); _cimg_keycode(T); _cimg_keycode(Y);
6847 _cimg_keycode(U); _cimg_keycode(I); _cimg_keycode(O); _cimg_keycode(P);
6848 _cimg_keycode(DELETE); _cimg_keycode(END); _cimg_keycode(PAGEDOWN);
6849 _cimg_keycode(CAPSLOCK); _cimg_keycode(A); _cimg_keycode(S); _cimg_keycode(D);
6850 _cimg_keycode(F); _cimg_keycode(G); _cimg_keycode(H); _cimg_keycode(J);
6851 _cimg_keycode(K); _cimg_keycode(L); _cimg_keycode(ENTER);
6852 _cimg_keycode(SHIFTLEFT); _cimg_keycode(Z); _cimg_keycode(X); _cimg_keycode(C);
6853 _cimg_keycode(V); _cimg_keycode(B); _cimg_keycode(N); _cimg_keycode(M);
6854 _cimg_keycode(SHIFTRIGHT); _cimg_keycode(ARROWUP); _cimg_keycode(CTRLLEFT);
6855 _cimg_keycode(APPLEFT); _cimg_keycode(ALT); _cimg_keycode(SPACE); _cimg_keycode(ALTGR);
6856 _cimg_keycode(APPRIGHT); _cimg_keycode(MENU); _cimg_keycode(CTRLRIGHT);
6857 _cimg_keycode(ARROWLEFT); _cimg_keycode(ARROWDOWN); _cimg_keycode(ARROWRIGHT);
6858 _cimg_keycode(PAD0); _cimg_keycode(PAD1); _cimg_keycode(PAD2);
6859 _cimg_keycode(PAD3); _cimg_keycode(PAD4); _cimg_keycode(PAD5);
6860 _cimg_keycode(PAD6); _cimg_keycode(PAD7); _cimg_keycode(PAD8);
6861 _cimg_keycode(PAD9); _cimg_keycode(PADADD); _cimg_keycode(PADSUB);
6862 _cimg_keycode(PADMUL); _cimg_keycode(PADDIV);
6873 const float delta = (
cimg::time()-_fps_timer)/1000.0f;
6876 _fps_fps = _fps_frames/delta;
6897 template<
typename T>
6912 template<
typename T>
6947 return assign(pos_x,pos_y);
6960 resize(_window_width,_window_height,force_redraw);
6974 return assign(width,height,0,3,force_redraw);
6987 template<
typename T>
6989 return resize(img._width,img._height,force_redraw);
7001 return resize(disp._width,disp._height,force_redraw);
7005 template<
typename t,
typename T>
7006 static void _render_resize(
const T *ptrs,
const unsigned int ws,
const unsigned int hs,
7007 t *ptrd,
const unsigned int wd,
const unsigned int hd) {
7008 unsigned int *
const offx =
new unsigned int[wd], *
const offy =
new unsigned int[hd+1], *poffx, *poffy;
7011 poffx = offx; curr = 0;
for (
unsigned int x = 0; x<wd; ++x) { old = curr; curr+=s; *(poffx++) = (
unsigned int)curr - (
unsigned int)old; }
7013 poffy = offy; curr = 0;
for (
unsigned int y = 0; y<hd; ++y) { old = curr; curr+=s; *(poffy++) = ws*((
unsigned int)curr - (
unsigned int)old); }
7016 for (
unsigned int y = 0; y<hd; ) {
7017 const T *ptr = ptrs;
7019 for (
unsigned int x = 0; x<wd; ++x) { *(ptrd++) = *ptr; ptr+=*(poffx++); }
7021 unsigned int dy = *(poffy++);
7022 for ( ; !dy && y<hd; std::memcpy(ptrd,ptrd - wd,
sizeof(t)*wd), ++y, ptrd+=wd, dy = *(poffy++)) {}
7025 delete[] offx;
delete[] offy;
7054 return assign(0,0,format);
7071 if (
is_empty() || _is_fullscreen==is_fullscreen)
return *
this;
7083 return assign(_width,_height,0,3,force_redraw);
7107 return assign(pos_x,pos_y);
7128 const unsigned int buttoncode = button==1?1:button==2?2:button==3?4:0;
7129 if (is_pressed) _button |= buttoncode;
else _button &= ~buttoncode;
7130 _is_event = buttoncode?
true:
false;
7151 _is_event = amplitude?
true:
false;
7160 std::memset((
void*)_keys,0,
sizeof(_keys));
7161 std::memset((
void*)_released_keys,0,
sizeof(_released_keys));
7162 _is_keyESC = _is_keyF1 = _is_keyF2 = _is_keyF3 = _is_keyF4 = _is_keyF5 = _is_keyF6 = _is_keyF7 = _is_keyF8 = _is_keyF9 =
7163 _is_keyF10 = _is_keyF11 = _is_keyF12 = _is_keyPAUSE = _is_key1 = _is_key2 = _is_key3 = _is_key4 = _is_key5 = _is_key6 =
7164 _is_key7 = _is_key8 = _is_key9 = _is_key0 = _is_keyBACKSPACE = _is_keyINSERT = _is_keyHOME = _is_keyPAGEUP = _is_keyTAB =
7165 _is_keyQ = _is_keyW = _is_keyE = _is_keyR = _is_keyT = _is_keyY = _is_keyU = _is_keyI = _is_keyO = _is_keyP = _is_keyDELETE =
7166 _is_keyEND = _is_keyPAGEDOWN = _is_keyCAPSLOCK = _is_keyA = _is_keyS = _is_keyD = _is_keyF = _is_keyG = _is_keyH = _is_keyJ =
7167 _is_keyK = _is_keyL = _is_keyENTER = _is_keySHIFTLEFT = _is_keyZ = _is_keyX = _is_keyC = _is_keyV = _is_keyB = _is_keyN =
7168 _is_keyM = _is_keySHIFTRIGHT = _is_keyARROWUP = _is_keyCTRLLEFT = _is_keyAPPLEFT = _is_keyALT = _is_keySPACE = _is_keyALTGR = _is_keyAPPRIGHT =
7169 _is_keyMENU = _is_keyCTRLRIGHT = _is_keyARROWLEFT = _is_keyARROWDOWN = _is_keyARROWRIGHT = _is_keyPAD0 = _is_keyPAD1 = _is_keyPAD2 =
7170 _is_keyPAD3 = _is_keyPAD4 = _is_keyPAD5 = _is_keyPAD6 = _is_keyPAD7 = _is_keyPAD8 = _is_keyPAD9 = _is_keyPADADD = _is_keyPADSUB =
7171 _is_keyPADMUL = _is_keyPADDIV =
false;
7184 #define _cimg_set_key(k) if (keycode==cimg::key##k) _is_key##k = is_pressed;
7185 _cimg_set_key(ESC); _cimg_set_key(F1); _cimg_set_key(F2); _cimg_set_key(F3);
7186 _cimg_set_key(F4); _cimg_set_key(F5); _cimg_set_key(F6); _cimg_set_key(F7);
7187 _cimg_set_key(F8); _cimg_set_key(F9); _cimg_set_key(F10); _cimg_set_key(F11);
7188 _cimg_set_key(F12); _cimg_set_key(PAUSE); _cimg_set_key(1); _cimg_set_key(2);
7189 _cimg_set_key(3); _cimg_set_key(4); _cimg_set_key(5); _cimg_set_key(6);
7190 _cimg_set_key(7); _cimg_set_key(8); _cimg_set_key(9); _cimg_set_key(0);
7191 _cimg_set_key(BACKSPACE); _cimg_set_key(INSERT); _cimg_set_key(HOME);
7192 _cimg_set_key(PAGEUP); _cimg_set_key(TAB); _cimg_set_key(Q); _cimg_set_key(W);
7193 _cimg_set_key(E); _cimg_set_key(R); _cimg_set_key(T); _cimg_set_key(Y);
7194 _cimg_set_key(U); _cimg_set_key(I); _cimg_set_key(O); _cimg_set_key(P);
7195 _cimg_set_key(DELETE); _cimg_set_key(END); _cimg_set_key(PAGEDOWN);
7196 _cimg_set_key(CAPSLOCK); _cimg_set_key(A); _cimg_set_key(S); _cimg_set_key(D);
7197 _cimg_set_key(F); _cimg_set_key(G); _cimg_set_key(H); _cimg_set_key(J);
7198 _cimg_set_key(K); _cimg_set_key(L); _cimg_set_key(ENTER);
7199 _cimg_set_key(SHIFTLEFT); _cimg_set_key(Z); _cimg_set_key(X); _cimg_set_key(C);
7200 _cimg_set_key(V); _cimg_set_key(B); _cimg_set_key(N); _cimg_set_key(M);
7201 _cimg_set_key(SHIFTRIGHT); _cimg_set_key(ARROWUP); _cimg_set_key(CTRLLEFT);
7202 _cimg_set_key(APPLEFT); _cimg_set_key(ALT); _cimg_set_key(SPACE); _cimg_set_key(ALTGR);
7203 _cimg_set_key(APPRIGHT); _cimg_set_key(MENU); _cimg_set_key(CTRLRIGHT);
7204 _cimg_set_key(ARROWLEFT); _cimg_set_key(ARROWDOWN); _cimg_set_key(ARROWRIGHT);
7205 _cimg_set_key(PAD0); _cimg_set_key(PAD1); _cimg_set_key(PAD2);
7206 _cimg_set_key(PAD3); _cimg_set_key(PAD4); _cimg_set_key(PAD5);
7207 _cimg_set_key(PAD6); _cimg_set_key(PAD7); _cimg_set_key(PAD8);
7208 _cimg_set_key(PAD9); _cimg_set_key(PADADD); _cimg_set_key(PADSUB);
7209 _cimg_set_key(PADMUL); _cimg_set_key(PADDIV);
7212 std::memmove((
void*)(_keys+1),(
void*)_keys,
sizeof(_keys) -
sizeof(
unsigned int));
7214 if (*_released_keys) {
7215 std::memmove((
void*)(_released_keys+1),(
void*)_released_keys,
sizeof(_released_keys) -
sizeof(
unsigned int));
7216 *_released_keys = 0;
7220 std::memmove((
void*)(_keys+1),(
void*)_keys,
sizeof(_keys) -
sizeof(
unsigned int));
7223 if (*_released_keys)
7224 std::memmove((
void*)(_released_keys+1),(
void*)_released_keys,
sizeof(_released_keys) -
sizeof(
unsigned int));
7227 _is_event = keycode?
true:
false;
7237 _is_resized = _is_moved = _is_event =
false;
7238 _fps_timer = _fps_frames = _timer = 0;
7255 cimg::_wait(milliseconds,_timer);
7261 disp1._is_event = 0;
7262 while (!disp1._is_closed && !disp1._is_event)
wait_all();
7267 disp1._is_event = disp2._is_event = 0;
7268 while ((!disp1._is_closed || !disp2._is_closed) &&
7269 !disp1._is_event && !disp2._is_event)
wait_all();
7274 disp1._is_event = disp2._is_event = disp3._is_event = 0;
7275 while ((!disp1._is_closed || !disp2._is_closed || !disp3._is_closed) &&
7276 !disp1._is_event && !disp2._is_event && !disp3._is_event)
wait_all();
7281 disp1._is_event = disp2._is_event = disp3._is_event = disp4._is_event = 0;
7282 while ((!disp1._is_closed || !disp2._is_closed || !disp3._is_closed || !disp4._is_closed) &&
7283 !disp1._is_event && !disp2._is_event && !disp3._is_event && !disp4._is_event)
wait_all();
7288 disp1._is_event = disp2._is_event = disp3._is_event = disp4._is_event = disp5._is_event = 0;
7289 while ((!disp1._is_closed || !disp2._is_closed || !disp3._is_closed || !disp4._is_closed || !disp5._is_closed) &&
7290 !disp1._is_event && !disp2._is_event && !disp3._is_event && !disp4._is_event && !disp5._is_event)
wait_all();
7296 disp1._is_event = disp2._is_event = disp3._is_event = disp4._is_event = disp5._is_event =
7297 disp6._is_event = 0;
7298 while ((!disp1._is_closed || !disp2._is_closed || !disp3._is_closed || !disp4._is_closed || !disp5._is_closed ||
7299 !disp6._is_closed) &&
7300 !disp1._is_event && !disp2._is_event && !disp3._is_event && !disp4._is_event && !disp5._is_event &&
7307 disp1._is_event = disp2._is_event = disp3._is_event = disp4._is_event = disp5._is_event =
7308 disp6._is_event = disp7._is_event = 0;
7309 while ((!disp1._is_closed || !disp2._is_closed || !disp3._is_closed || !disp4._is_closed || !disp5._is_closed ||
7310 !disp6._is_closed || !disp7._is_closed) &&
7311 !disp1._is_event && !disp2._is_event && !disp3._is_event && !disp4._is_event && !disp5._is_event &&
7312 !disp6._is_event && !disp7._is_event)
wait_all();
7318 disp1._is_event = disp2._is_event = disp3._is_event = disp4._is_event = disp5._is_event =
7319 disp6._is_event = disp7._is_event = disp8._is_event = 0;
7320 while ((!disp1._is_closed || !disp2._is_closed || !disp3._is_closed || !disp4._is_closed || !disp5._is_closed ||
7321 !disp6._is_closed || !disp7._is_closed || !disp8._is_closed) &&
7322 !disp1._is_event && !disp2._is_event && !disp3._is_event && !disp4._is_event && !disp5._is_event &&
7323 !disp6._is_event && !disp7._is_event && !disp8._is_event)
wait_all();
7329 disp1._is_event = disp2._is_event = disp3._is_event = disp4._is_event = disp5._is_event =
7330 disp6._is_event = disp7._is_event = disp8._is_event = disp9._is_event = 0;
7331 while ((!disp1._is_closed || !disp2._is_closed || !disp3._is_closed || !disp4._is_closed || !disp5._is_closed ||
7332 !disp6._is_closed || !disp7._is_closed || !disp8._is_closed || !disp9._is_closed) &&
7333 !disp1._is_event && !disp2._is_event && !disp3._is_event && !disp4._is_event && !disp5._is_event &&
7334 !disp6._is_event && !disp7._is_event && !disp8._is_event && !disp9._is_event)
wait_all();
7340 disp1._is_event = disp2._is_event = disp3._is_event = disp4._is_event = disp5._is_event =
7341 disp6._is_event = disp7._is_event = disp8._is_event = disp9._is_event = disp10._is_event = 0;
7342 while ((!disp1._is_closed || !disp2._is_closed || !disp3._is_closed || !disp4._is_closed || !disp5._is_closed ||
7343 !disp6._is_closed || !disp7._is_closed || !disp8._is_closed || !disp9._is_closed || !disp10._is_closed) &&
7344 !disp1._is_event && !disp2._is_event && !disp3._is_event && !disp4._is_event && !disp5._is_event &&
7345 !disp6._is_event && !disp7._is_event && !disp8._is_event && !disp9._is_event && !disp10._is_event)
wait_all();
7352 return _no_display_exception();
7363 template<
typename T>
7382 template<
typename T>
7385 _no_display_exception();
7394 Atom _wm_window_atom, _wm_protocol_atom;
7395 Window _window, _background_window;
7399 #ifdef cimg_use_xshm
7400 XShmSegmentInfo *_shminfo;
7404 Display *
const dpy = cimg::X11_attr().display;
7407 Display *
const _dpy = XOpenDisplay(0);
7410 res = DisplayWidth(_dpy,DefaultScreen(_dpy));
7411 XCloseDisplay(_dpy);
7413 #ifdef cimg_use_xrandr
7414 if (cimg::X11_attr().resolutions && cimg::X11_attr().curr_resolution)
7415 res = cimg::X11_attr().resolutions[cimg::X11_attr().curr_resolution].width;
7416 else res = DisplayWidth(dpy,DefaultScreen(dpy));
7418 res = DisplayWidth(dpy,DefaultScreen(dpy));
7425 Display *
const dpy = cimg::X11_attr().display;
7428 Display *
const _dpy = XOpenDisplay(0);
7430 throw CImgDisplayException(
"CImgDisplay::screen_height(): Failed to open X11 display.");
7431 res = DisplayHeight(_dpy,DefaultScreen(_dpy));
7432 XCloseDisplay(_dpy);
7434 #ifdef cimg_use_xrandr
7435 if (cimg::X11_attr().resolutions && cimg::X11_attr().curr_resolution)
7436 res = cimg::X11_attr().resolutions[cimg::X11_attr().curr_resolution].height;
7437 else res = DisplayHeight(dpy,DefaultScreen(dpy));
7439 res = DisplayHeight(dpy,DefaultScreen(dpy));
7446 Display *
const dpy = cimg::X11_attr().display;
7452 XNextEvent(dpy,&event);
7453 for (
unsigned int i = 0; i<cimg::X11_attr().nb_wins; ++i)
7454 if (!cimg::X11_attr().wins[i]->_is_closed &&
event.xany.window==cimg::X11_attr().wins[i]->_window) {
7455 cimg::X11_attr().wins[i]->_handle_events(&event);
7456 if (cimg::X11_attr().wins[i]->_is_event) flag =
false;
7459 XUnlockDisplay(dpy);
7462 void _handle_events(
const XEvent *
const pevent) {
7463 Display *
const dpy = cimg::X11_attr().display;
7464 XEvent
event = *pevent;
7465 switch (event.type) {
7466 case ClientMessage : {
7467 if ((
int)event.xclient.message_type==(
int)_wm_protocol_atom &&
7468 (
int)event.xclient.data.l[0]==(
int)_wm_window_atom) {
7469 XUnmapWindow(cimg::X11_attr().
display,_window);
7470 _is_closed = _is_event =
true;
7473 case ConfigureNotify : {
7474 while (XCheckWindowEvent(dpy,_window,StructureNotifyMask,&event)) {}
7475 const unsigned int nw =
event.xconfigure.width, nh =
event.xconfigure.height;
7476 const int nx =
event.xconfigure.x, ny =
event.xconfigure.y;
7477 if (nw && nh && (nw!=_window_width || nh!=_window_height)) {
7478 _window_width = nw; _window_height = nh; _mouse_x = _mouse_y = -1;
7479 XResizeWindow(dpy,_window,_window_width,_window_height);
7480 _is_resized = _is_event =
true;
7482 if (nx!=_window_x || ny!=_window_y) { _window_x = nx; _window_y = ny; _is_moved = _is_event =
true; }
7485 while (XCheckWindowEvent(dpy,_window,ExposureMask,&event)) {}
7487 if (_is_fullscreen) {
7488 XWindowAttributes attr;
7489 XGetWindowAttributes(dpy,_window,&attr);
7490 while (attr.map_state!=IsViewable) XSync(dpy,0);
7491 XSetInputFocus(dpy,_window,RevertToParent,CurrentTime);
7494 case ButtonPress : {
7496 _mouse_x =
event.xmotion.x; _mouse_y =
event.xmotion.y;
7497 if (_mouse_x<0 || _mouse_y<0 || _mouse_x>=
width() || _mouse_y>=
height()) _mouse_x = _mouse_y = -1;
7498 switch (event.xbutton.button) {
7503 }
while (XCheckWindowEvent(dpy,_window,ButtonPressMask,&event));
7505 case ButtonRelease : {
7507 _mouse_x =
event.xmotion.x; _mouse_y =
event.xmotion.y;
7508 if (_mouse_x<0 || _mouse_y<0 || _mouse_x>=
width() || _mouse_y>=
height()) _mouse_x = _mouse_y = -1;
7509 switch (event.xbutton.button) {
7516 }
while (XCheckWindowEvent(dpy,_window,ButtonReleaseMask,&event));
7519 char tmp = 0; KeySym ksym;
7520 XLookupString(&event.xkey,&tmp,1,&ksym,0);
7521 set_key((
unsigned int)ksym,
true);
7524 char keys_return[32];
7525 XQueryKeymap(dpy,keys_return);
7526 const unsigned int kc =
event.xkey.keycode, kc1 = kc/8, kc2 = kc%8;
7527 const bool is_key_pressed = kc1>=32?
false:(keys_return[kc1]>>kc2)&1;
7528 if (!is_key_pressed) {
7529 char tmp = 0; KeySym ksym;
7530 XLookupString(&event.xkey,&tmp,1,&ksym,0);
7531 set_key((
unsigned int)ksym,
false);
7535 while (XCheckWindowEvent(dpy,_window,EnterWindowMask,&event)) {}
7536 _mouse_x =
event.xmotion.x;
7537 _mouse_y =
event.xmotion.y;
7538 if (_mouse_x<0 || _mouse_y<0 || _mouse_x>=
width() || _mouse_y>=
height()) _mouse_x = _mouse_y = -1;
7540 case LeaveNotify : {
7541 while (XCheckWindowEvent(dpy,_window,LeaveWindowMask,&event)) {}
7542 _mouse_x = _mouse_y =-1; _is_event =
true;
7544 case MotionNotify : {
7545 while (XCheckWindowEvent(dpy,_window,PointerMotionMask,&event)) {}
7546 _mouse_x =
event.xmotion.x;
7547 _mouse_y =
event.xmotion.y;
7548 if (_mouse_x<0 || _mouse_y<0 || _mouse_x>=
width() || _mouse_y>=
height()) _mouse_x = _mouse_y = -1;
7554 static void* _events_thread(
void *) {
7555 Display *
const dpy = cimg::X11_attr().display;
7557 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,0);
7558 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,0);
7561 bool event_flag = XCheckTypedEvent(dpy,ClientMessage,&event);
7562 if (!event_flag) event_flag = XCheckMaskEvent(dpy,
7563 ExposureMask | StructureNotifyMask | ButtonPressMask|
7564 KeyPressMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask|
7565 ButtonReleaseMask | KeyReleaseMask,&event);
7567 for (
unsigned int i = 0; i<cimg::X11_attr().nb_wins; ++i)
7568 if (!cimg::X11_attr().wins[i]->_is_closed &&
event.xany.window==cimg::X11_attr().wins[i]->_window)
7569 cimg::X11_attr().wins[i]->_handle_events(&event);
7570 XUnlockDisplay(dpy);
7571 pthread_testcancel();
7577 void _set_colormap(Colormap& _colormap,
const unsigned int dim) {
7578 XColor colormap[256];
7581 for (
unsigned int index = 0; index<256; ++index) {
7582 colormap[index].pixel = index;
7583 colormap[index].red = colormap[index].green = colormap[index].blue = (
unsigned short)(index<<8);
7584 colormap[index].flags = DoRed | DoGreen | DoBlue;
7588 for (
unsigned int index = 0, r = 8; r<256; r+=16)
7589 for (
unsigned int g = 8; g<256; g+=16) {
7590 colormap[index].pixel = index;
7591 colormap[index].red = colormap[index].blue = (
unsigned short)(r<<8);
7592 colormap[index].green = (
unsigned short)(g<<8);
7593 colormap[index++].flags = DoRed | DoGreen | DoBlue;
7597 for (
unsigned int index = 0, r = 16; r<256; r+=32)
7598 for (
unsigned int g = 16; g<256; g+=32)
7599 for (
unsigned int b = 32; b<256; b+=64) {
7600 colormap[index].pixel = index;
7601 colormap[index].red = (
unsigned short)(r<<8);
7602 colormap[index].green = (
unsigned short)(g<<8);
7603 colormap[index].blue = (
unsigned short)(b<<8);
7604 colormap[index++].flags = DoRed | DoGreen | DoBlue;
7608 XStoreColors(cimg::X11_attr().
display,_colormap,colormap,256);
7611 void _map_window() {
7612 Display *
const dpy = cimg::X11_attr().display;
7613 bool is_exposed =
false, is_mapped =
false;
7614 XWindowAttributes attr;
7616 XMapRaised(dpy,_window);
7618 XWindowEvent(dpy,_window,StructureNotifyMask | ExposureMask,&event);
7619 switch (event.type) {
7620 case MapNotify : is_mapped =
true;
break;
7621 case Expose : is_exposed =
true;
break;
7623 }
while (!is_exposed || !is_mapped);
7625 XGetWindowAttributes(dpy,_window,&attr);
7626 if (attr.map_state!=IsViewable) { XSync(dpy,0);
cimg::sleep(10); }
7627 }
while (attr.map_state!=IsViewable);
7632 void _paint(
const bool wait_expose=
true) {
7633 if (_is_closed || !_image)
return;
7634 Display *
const dpy = cimg::X11_attr().display;
7636 static XEvent event;
7637 event.xexpose.type = Expose;
7638 event.xexpose.serial = 0;
7639 event.xexpose.send_event = 1;
7640 event.xexpose.display = dpy;
7641 event.xexpose.window = _window;
7642 event.xexpose.x = 0;
7643 event.xexpose.y = 0;
7644 event.xexpose.width =
width();
7645 event.xexpose.height =
height();
7646 event.xexpose.count = 0;
7647 XSendEvent(dpy,_window,0,0,&event);
7649 GC gc = DefaultGC(dpy,DefaultScreen(dpy));
7650 #ifdef cimg_use_xshm
7652 const int completion_type = XShmGetEventBase(dpy) + ShmCompletion;
7654 XShmPutImage(dpy,_window,gc,_image,0,0,0,0,_width,_height,1);
7655 do { XNextEvent(dpy,&event); }
while (event.type!=completion_type);
7656 }
else XPutImage(dpy,_window,gc,_image,0,0,0,0,_width,_height);
7658 XPutImage(dpy,_window,gc,_image,0,0,0,0,_width,_height);
7663 template<
typename T>
7664 void _resize(T pixel_type,
const unsigned int ndimx,
const unsigned int ndimy,
const bool force_redraw) {
7665 Display *
const dpy = cimg::X11_attr().display;
7668 #ifdef cimg_use_xshm
7670 XShmSegmentInfo *
const nshminfo =
new XShmSegmentInfo;
7671 XImage *
const nimage = XShmCreateImage(dpy,DefaultVisual(dpy,DefaultScreen(dpy)),
7672 cimg::X11_attr().nb_bits,ZPixmap,0,nshminfo,ndimx,ndimy);
7673 if (!nimage) {
delete nshminfo;
return; }
7675 nshminfo->shmid = shmget(IPC_PRIVATE,ndimx*ndimy*
sizeof(T),IPC_CREAT | 0777);
7676 if (nshminfo->shmid==-1) { XDestroyImage(nimage);
delete nshminfo;
return; }
7678 nshminfo->shmaddr = nimage->data = (
char*)shmat(nshminfo->shmid,0,0);
7679 if (nshminfo->shmaddr==(
char*)-1) { shmctl(nshminfo->shmid,IPC_RMID,0); XDestroyImage(nimage);
delete nshminfo;
return; }
7681 nshminfo->readOnly = 0;
7682 cimg::X11_attr().is_shm_enabled =
true;
7683 XErrorHandler oldXErrorHandler = XSetErrorHandler(_assign_xshm);
7684 XShmAttach(dpy,nshminfo);
7686 XSetErrorHandler(oldXErrorHandler);
7687 if (!cimg::X11_attr().is_shm_enabled) {
7688 shmdt(nshminfo->shmaddr);
7689 shmctl(nshminfo->shmid,IPC_RMID,0);
7690 XDestroyImage(nimage);
7694 T *
const ndata = (T*)nimage->data;
7695 if (force_redraw) _render_resize((T*)_data,_width,_height,ndata,ndimx,ndimy);
7696 else std::memset(ndata,0,
sizeof(T)*ndimx*ndimy);
7697 XShmDetach(dpy,_shminfo);
7698 XDestroyImage(_image);
7699 shmdt(_shminfo->shmaddr);
7700 shmctl(_shminfo->shmid,IPC_RMID,0);
7702 _shminfo = nshminfo;
7704 _data = (
void*)ndata;
7712 T *ndata = (T*)std::malloc(ndimx*ndimy*
sizeof(T));
7713 if (force_redraw) _render_resize((T*)_data,_width,_height,ndata,ndimx,ndimy);
7714 else std::memset(ndata,0,
sizeof(T)*ndimx*ndimy);
7715 _data = (
void*)ndata;
7716 XDestroyImage(_image);
7717 _image = XCreateImage(dpy,DefaultVisual(dpy,DefaultScreen(dpy)),
7718 cimg::X11_attr().nb_bits,ZPixmap,0,(
char*)_data,ndimx,ndimy,8,0);
7722 void _init_fullscreen() {
7723 if (!_is_fullscreen || _is_closed)
return;
7724 Display *
const dpy = cimg::X11_attr().display;
7725 _background_window = 0;
7727 #ifdef cimg_use_xrandr
7729 if (XRRQueryExtension(dpy,&foo,&foo)) {
7730 XRRRotations(dpy,DefaultScreen(dpy),&cimg::X11_attr().curr_rotation);
7731 if (!cimg::X11_attr().resolutions) {
7732 cimg::X11_attr().resolutions = XRRSizes(dpy,DefaultScreen(dpy),&foo);
7733 cimg::X11_attr().nb_resolutions = (
unsigned int)foo;
7735 if (cimg::X11_attr().resolutions) {
7736 cimg::X11_attr().curr_resolution = 0;
7737 for (
unsigned int i = 0; i<cimg::X11_attr().nb_resolutions; ++i) {
7739 nw = (
unsigned int)(cimg::X11_attr().resolutions[i].width),
7740 nh = (
unsigned int)(cimg::X11_attr().resolutions[i].height);
7741 if (nw>=_width && nh>=_height &&
7742 nw<=(
unsigned int)(cimg::X11_attr().resolutions[cimg::X11_attr().curr_resolution].width) &&
7743 nh<=(
unsigned int)(cimg::X11_attr().resolutions[cimg::X11_attr().curr_resolution].height))
7744 cimg::X11_attr().curr_resolution = i;
7746 if (cimg::X11_attr().curr_resolution>0) {
7747 XRRScreenConfiguration *config = XRRGetScreenInfo(dpy,DefaultRootWindow(dpy));
7748 XRRSetScreenConfig(dpy,config,DefaultRootWindow(dpy),
7749 cimg::X11_attr().curr_resolution,cimg::X11_attr().curr_rotation,CurrentTime);
7750 XRRFreeScreenConfigInfo(config);
7755 if (!cimg::X11_attr().resolutions)
7757 "init_fullscreen(): Xrandr extension not supported by the X server.",
7758 cimgdisplay_instance);
7762 if (sx==_width && sy==_height)
return;
7763 XSetWindowAttributes winattr;
7764 winattr.override_redirect = 1;
7765 _background_window = XCreateWindow(dpy,DefaultRootWindow(dpy),0,0,sx,sy,0,0,
7766 InputOutput,CopyFromParent,CWOverrideRedirect,&winattr);
7767 const unsigned long buf_size = (
unsigned long)sx*sy*(cimg::X11_attr().nb_bits==8?1:(cimg::X11_attr().nb_bits==16?2:4));
7768 void *background_data = std::malloc(buf_size);
7769 std::memset(background_data,0,buf_size);
7770 XImage *background_image = XCreateImage(dpy,DefaultVisual(dpy,DefaultScreen(dpy)),cimg::X11_attr().nb_bits,
7771 ZPixmap,0,(
char*)background_data,sx,sy,8,0);
7773 XSelectInput(dpy,_background_window,StructureNotifyMask);
7774 XMapRaised(dpy,_background_window);
7775 do XWindowEvent(dpy,_background_window,StructureNotifyMask,&event);
7776 while (event.type!=MapNotify);
7777 GC gc = DefaultGC(dpy,DefaultScreen(dpy));
7778 #ifdef cimg_use_xshm
7779 if (_shminfo) XShmPutImage(dpy,_background_window,gc,background_image,0,0,0,0,sx,sy,0);
7780 else XPutImage(dpy,_background_window,gc,background_image,0,0,0,0,sx,sy);
7782 XPutImage(dpy,_background_window,gc,background_image,0,0,0,0,sx,sy);
7784 XWindowAttributes attr;
7785 XGetWindowAttributes(dpy,_background_window,&attr);
7786 while (attr.map_state!=IsViewable) XSync(dpy,0);
7787 XDestroyImage(background_image);
7790 void _desinit_fullscreen() {
7791 if (!_is_fullscreen)
return;
7792 Display *
const dpy = cimg::X11_attr().display;
7793 XUngrabKeyboard(dpy,CurrentTime);
7794 #ifdef cimg_use_xrandr
7795 if (cimg::X11_attr().resolutions && cimg::X11_attr().curr_resolution) {
7796 XRRScreenConfiguration *config = XRRGetScreenInfo(dpy,DefaultRootWindow(dpy));
7797 XRRSetScreenConfig(dpy,config,DefaultRootWindow(dpy),0,cimg::X11_attr().curr_rotation,CurrentTime);
7798 XRRFreeScreenConfigInfo(config);
7800 cimg::X11_attr().curr_resolution = 0;
7803 if (_background_window) XDestroyWindow(dpy,_background_window);
7804 _background_window = 0;
7805 _is_fullscreen =
false;
7808 static int _assign_xshm(Display *dpy, XErrorEvent *error) {
7810 cimg::X11_attr().is_shm_enabled =
false;
7814 void _assign(
const unsigned int dimw,
const unsigned int dimh,
const char *
const ptitle=0,
7815 const unsigned int normalization_type=3,
7816 const bool fullscreen_flag=
false,
const bool closed_flag=
false) {
7819 const char *
const nptitle = ptitle?ptitle:
"";
7820 const unsigned int s = std::strlen(nptitle) + 1;
7821 char *
const tmp_title = s?
new char[s]:0;
7822 if (s) std::memcpy(tmp_title,nptitle,s*
sizeof(
char));
7828 Display* &dpy = cimg::X11_attr().display;
7830 static const int xinit_status = XInitThreads();
7832 dpy = XOpenDisplay(0);
7834 throw CImgDisplayException(_cimgdisplay_instance
7835 "assign(): Failed to open X11 display.",
7836 cimgdisplay_instance);
7838 cimg::X11_attr().nb_bits = DefaultDepth(dpy,DefaultScreen(dpy));
7839 if (cimg::X11_attr().nb_bits!=8 && cimg::X11_attr().nb_bits!=16 && cimg::X11_attr().nb_bits!=24 && cimg::X11_attr().nb_bits!=32)
7840 throw CImgDisplayException(_cimgdisplay_instance
7841 "assign(): Invalid %u bits screen mode detected "
7842 "(only 8, 16, 24 and 32 bits modes are managed).",
7843 cimgdisplay_instance,
7844 cimg::X11_attr().nb_bits);
7845 XVisualInfo vtemplate;
7846 vtemplate.visualid = XVisualIDFromVisual(DefaultVisual(dpy,DefaultScreen(dpy)));
7848 XVisualInfo *vinfo = XGetVisualInfo(dpy,VisualIDMask,&vtemplate,&nb_visuals);
7849 if (vinfo && vinfo->red_mask<vinfo->blue_mask) cimg::X11_attr().is_blue_first =
true;
7850 cimg::X11_attr().byte_order = ImageByteOrder(dpy);
7854 cimg::X11_attr().event_thread =
new pthread_t;
7855 pthread_create(cimg::X11_attr().event_thread,0,_events_thread,0);
7856 }
else XLockDisplay(dpy);
7861 _normalization = normalization_type<4?normalization_type:3;
7862 _is_fullscreen = fullscreen_flag;
7863 _window_x = _window_y = 0;
7864 _is_closed = closed_flag;
7869 if (_is_fullscreen) {
7870 if (!_is_closed) _init_fullscreen();
7872 XSetWindowAttributes winattr;
7873 winattr.override_redirect = 1;
7874 _window = XCreateWindow(dpy,DefaultRootWindow(dpy),(sx-_width)/2,(sy-_height)/2,_width,_height,0,0,
7875 InputOutput,CopyFromParent,CWOverrideRedirect,&winattr);
7877 _window = XCreateSimpleWindow(dpy,DefaultRootWindow(dpy),0,0,_width,_height,0,0L,0L);
7879 XSelectInput(dpy,_window,
7880 ExposureMask | StructureNotifyMask | ButtonPressMask | KeyPressMask | PointerMotionMask |
7881 EnterWindowMask | LeaveWindowMask | ButtonReleaseMask | KeyReleaseMask);
7883 XStoreName(dpy,_window,_title?_title:
" ");
7884 if (cimg::X11_attr().nb_bits==8) {
7885 _colormap = XCreateColormap(dpy,_window,DefaultVisual(dpy,DefaultScreen(dpy)),AllocAll);
7886 _set_colormap(_colormap,3);
7887 XSetWindowColormap(dpy,_window,_colormap);
7890 static const char *
const _window_class = cimg_appname;
7891 XClassHint *
const window_class = XAllocClassHint();
7892 window_class->res_name = (
char*)_window_class;
7893 window_class->res_class = (
char*)_window_class;
7894 XSetClassHint(dpy,_window,window_class);
7895 XFree(window_class);
7897 _window_width = _width;
7898 _window_height = _height;
7901 #ifdef cimg_use_xshm
7903 if (XShmQueryExtension(dpy)) {
7904 _shminfo =
new XShmSegmentInfo;
7905 _image = XShmCreateImage(dpy,DefaultVisual(dpy,DefaultScreen(dpy)),cimg::X11_attr().nb_bits,ZPixmap,0,_shminfo,_width,_height);
7906 if (!_image) {
delete _shminfo; _shminfo = 0; }
7908 _shminfo->shmid = shmget(IPC_PRIVATE,_image->bytes_per_line*_image->height,IPC_CREAT|0777);
7909 if (_shminfo->shmid==-1) { XDestroyImage(_image);
delete _shminfo; _shminfo = 0; }
7911 _shminfo->shmaddr = _image->data = (
char*)(_data = shmat(_shminfo->shmid,0,0));
7912 if (_shminfo->shmaddr==(
char*)-1) { shmctl(_shminfo->shmid,IPC_RMID,0); XDestroyImage(_image);
delete _shminfo; _shminfo = 0; }
7914 _shminfo->readOnly = 0;
7915 cimg::X11_attr().is_shm_enabled =
true;
7916 XErrorHandler oldXErrorHandler = XSetErrorHandler(_assign_xshm);
7917 XShmAttach(dpy,_shminfo);
7919 XSetErrorHandler(oldXErrorHandler);
7920 if (!cimg::X11_attr().is_shm_enabled) {
7921 shmdt(_shminfo->shmaddr); shmctl(_shminfo->shmid,IPC_RMID,0); XDestroyImage(_image);
delete _shminfo; _shminfo = 0;
7930 const unsigned long buf_size = (
unsigned long)_width*_height*(cimg::X11_attr().nb_bits==8?1:(cimg::X11_attr().nb_bits==16?2:4));
7931 _data = std::malloc(buf_size);
7932 _image = XCreateImage(dpy,DefaultVisual(dpy,DefaultScreen(dpy)),cimg::X11_attr().nb_bits,ZPixmap,0,(
char*)_data,_width,_height,8,0);
7935 _wm_window_atom = XInternAtom(dpy,
"WM_DELETE_WINDOW",0);
7936 _wm_protocol_atom = XInternAtom(dpy,
"WM_PROTOCOLS",0);
7937 XSetWMProtocols(dpy,_window,&_wm_window_atom,1);
7939 if (_is_fullscreen) XGrabKeyboard(dpy,_window,1,GrabModeAsync,GrabModeAsync,CurrentTime);
7940 cimg::X11_attr().wins[cimg::X11_attr().nb_wins++]=
this;
7941 if (!_is_closed) _map_window();
else { _window_x = _window_y = cimg::type<int>::min(); }
7942 XUnlockDisplay(dpy);
7947 Display *
const dpy = cimg::X11_attr().display;
7952 for (i = 0; i<cimg::X11_attr().nb_wins && cimg::X11_attr().wins[i]!=
this; ++i) {}
7953 for (; i<cimg::X11_attr().nb_wins-1; ++i) cimg::X11_attr().wins[i] = cimg::X11_attr().wins[i+1];
7954 --cimg::X11_attr().nb_wins;
7957 if (_is_fullscreen && !_is_closed) _desinit_fullscreen();
7958 XDestroyWindow(dpy,_window);
7960 #ifdef cimg_use_xshm
7962 XShmDetach(dpy,_shminfo);
7963 XDestroyImage(_image);
7964 shmdt(_shminfo->shmaddr);
7965 shmctl(_shminfo->shmid,IPC_RMID,0);
7970 XDestroyImage(_image);
7971 _data = 0; _image = 0;
7972 if (cimg::X11_attr().nb_bits==8) XFreeColormap(dpy,_colormap);
7978 _width = _height = _normalization = _window_width = _window_height = 0;
7979 _window_x = _window_y = 0;
7980 _is_fullscreen =
false;
7987 XUnlockDisplay(dpy);
7988 if (!cimg::X11_attr().nb_wins) {
8003 const unsigned int normalization_type=3,
8004 const bool fullscreen_flag=
false,
const bool closed_flag=
false) {
8005 if (!dimw || !dimh)
return assign();
8006 _assign(dimw,dimh,
title,normalization_type,fullscreen_flag,closed_flag);
8008 std::memset(_data,0,(cimg::X11_attr().nb_bits==8?
sizeof(
unsigned char):
8009 (cimg::X11_attr().nb_bits==16?
sizeof(
unsigned short):
sizeof(
unsigned int)))*(
unsigned long)_width*_height);
8013 template<
typename T>
8015 const unsigned int normalization_type=3,
8016 const bool fullscreen_flag=
false,
const bool closed_flag=
false) {
8017 if (!img)
return assign();
8019 const CImg<T>& nimg = (img._depth==1)?img:(tmp=img.get_projections2d(img._width/2,img._height/2,img._depth/2));
8020 _assign(nimg._width,nimg._height,
title,normalization_type,fullscreen_flag,closed_flag);
8021 if (_normalization==2) _min = (float)nimg.min_max(_max);
8025 template<
typename T>
8027 const unsigned int normalization_type=3,
8028 const bool fullscreen_flag=
false,
const bool closed_flag=
false) {
8029 if (!list)
return assign();
8031 const CImg<T> img = list>
'x', &nimg = (img._depth==1)?img:(tmp=img.get_projections2d(img._width/2,img._height/2,img._depth/2));
8032 _assign(nimg._width,nimg._height,
title,normalization_type,fullscreen_flag,closed_flag);
8033 if (_normalization==2) _min = (float)nimg.min_max(_max);
8038 if (!disp)
return assign();
8039 _assign(disp._width,disp._height,disp._title,disp._normalization,disp._is_fullscreen,disp._is_closed);
8040 std::memcpy(_data,disp._data,(cimg::X11_attr().nb_bits==8?
sizeof(
unsigned char):
8041 cimg::X11_attr().nb_bits==16?
sizeof(
unsigned short):
8042 sizeof(
unsigned int))*(
unsigned long)_width*_height);
8046 CImgDisplay&
resize(
const int nwidth,
const int nheight,
const bool force_redraw=
true) {
8047 if (!nwidth || !nheight || (
is_empty() && (nwidth<0 || nheight<0)))
return assign();
8049 Display *
const dpy = cimg::X11_attr().display;
8051 tmpdimx = (nwidth>0)?nwidth:(-nwidth*
width()/100),
8052 tmpdimy = (nheight>0)?nheight:(-nheight*
height()/100),
8053 dimx = tmpdimx?tmpdimx:1,
8054 dimy = tmpdimy?tmpdimy:1;
8056 if (_window_width!=dimx || _window_height!=dimy) XResizeWindow(dpy,_window,dimx,dimy);
8057 if (_width!=dimx || _height!=dimy)
switch (cimg::X11_attr().nb_bits) {
8058 case 8 : {
unsigned char pixel_type = 0; _resize(pixel_type,dimx,dimy,force_redraw); }
break;
8059 case 16 : {
unsigned short pixel_type = 0; _resize(pixel_type,dimx,dimy,force_redraw); }
break;
8060 default : {
unsigned int pixel_type = 0; _resize(pixel_type,dimx,dimy,force_redraw); }
8062 _window_width = _width = dimx; _window_height = _height = dimy;
8063 _is_resized =
false;
8064 XUnlockDisplay(dpy);
8066 if (force_redraw)
return paint();
8073 const unsigned long buf_size = (
unsigned long)_width*_height*(cimg::X11_attr().nb_bits==8?1:(cimg::X11_attr().nb_bits==16?2:4));
8074 void *image_data = std::malloc(buf_size);
8075 std::memcpy(image_data,_data,buf_size);
8076 assign(_width,_height,_title,_normalization,!_is_fullscreen,
false);
8077 std::memcpy(_data,image_data,buf_size);
8078 std::free(image_data);
8081 return assign(_width,_height,_title,_normalization,!_is_fullscreen,
false);
8085 if (
is_empty() || !_is_closed)
return *
this;
8086 Display *
const dpy = cimg::X11_attr().
display;
8088 if (_is_fullscreen) _init_fullscreen();
8091 XUnlockDisplay(dpy);
8096 if (
is_empty() || _is_closed)
return *
this;
8097 Display *
const dpy = cimg::X11_attr().
display;
8099 if (_is_fullscreen) _desinit_fullscreen();
8100 XUnmapWindow(dpy,_window);
8101 _window_x = _window_y = -1;
8103 XUnlockDisplay(dpy);
8109 Display *
const dpy = cimg::X11_attr().
display;
8112 XMoveWindow(dpy,_window,posx,posy);
8113 _window_x = posx; _window_y = posy;
8115 XUnlockDisplay(dpy);
8121 Display *
const dpy = cimg::X11_attr().
display;
8123 XUndefineCursor(dpy,_window);
8124 XUnlockDisplay(dpy);
8130 Display *
const dpy = cimg::X11_attr().
display;
8132 const char pix_data[8] = { 0 };
8134 col.red = col.green = col.blue = 0;
8135 Pixmap pix = XCreateBitmapFromData(dpy,_window,pix_data,8,8);
8136 Cursor cur = XCreatePixmapCursor(dpy,pix,pix,&col,&col,0,0);
8137 XFreePixmap(dpy,pix);
8138 XDefineCursor(dpy,_window,cur);
8139 XUnlockDisplay(dpy);
8144 if (
is_empty() || _is_closed)
return *
this;
8145 Display *
const dpy = cimg::X11_attr().
display;
8147 XWarpPointer(dpy,0L,_window,0,0,0,0,posx,posy);
8148 _mouse_x = posx; _mouse_y = posy;
8151 XUnlockDisplay(dpy);
8157 char tmp[1024] = { 0 };
8159 va_start(ap, format);
8160 cimg_vsnprintf(tmp,
sizeof(tmp),format,ap);
8162 if (!std::strcmp(_title,tmp))
return *
this;
8164 const unsigned int s = std::strlen(tmp) + 1;
8165 _title =
new char[s];
8166 std::memcpy(_title,tmp,s*
sizeof(
char));
8167 Display *
const dpy = cimg::X11_attr().display;
8169 XStoreName(dpy,_window,tmp);
8170 XUnlockDisplay(dpy);
8174 template<
typename T>
8177 throw CImgArgumentException(_cimgdisplay_instance
8178 "display(): Empty specified image.",
8179 cimgdisplay_instance);
8186 Display *
const dpy = cimg::X11_attr().
display;
8188 _paint(wait_expose);
8189 XUnlockDisplay(dpy);
8193 template<
typename T>
8196 throw CImgArgumentException(_cimgdisplay_instance
8197 "render(): Empty specified image.",
8198 cimgdisplay_instance);
8200 if (img._depth!=1)
return render(img.get_projections2d(img._width/2,img._height/2,img._depth/2));
8201 if (cimg::X11_attr().nb_bits==8 && (img._width!=_width || img._height!=_height))
return render(img.get_resize(_width,_height,1,-100,1));
8202 if (cimg::X11_attr().nb_bits==8 && !flag8 && img._spectrum==3) {
8203 static const CImg<typename CImg<T>::ucharT> default_colormap = CImg<typename CImg<T>::ucharT>::default_LUT256();
8204 return render(img.get_index(default_colormap,1,
false));
8207 Display *
const dpy = cimg::X11_attr().
display;
8210 *data2 = (img._spectrum>1)?img.data(0,0,0,1):data1,
8211 *data3 = (img._spectrum>2)?img.data(0,0,0,2):data1;
8213 if (cimg::X11_attr().is_blue_first)
cimg::swap(data1,data3);
8216 if (!_normalization || (_normalization==3 && cimg::type<T>::string()==cimg::type<unsigned char>::string())) {
8218 switch (cimg::X11_attr().nb_bits) {
8220 _set_colormap(_colormap,img._spectrum);
8221 unsigned char *
const ndata = (img._width==_width && img._height==_height)?(
unsigned char*)_data:
new unsigned char[(
unsigned long)img._width*img._height];
8222 unsigned char *ptrd = (
unsigned char*)ndata;
8223 switch (img._spectrum) {
8224 case 1 :
for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) (*ptrd++) = (
unsigned char)*(data1++);
8226 case 2 :
for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8227 const unsigned char R = (
unsigned char)*(data1++), G = (
unsigned char)*(data2++);
8228 (*ptrd++) = (R&0xf0) | (G>>4);
8230 default :
for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8231 const unsigned char R = (
unsigned char)*(data1++), G = (
unsigned char)*(data2++), B = (
unsigned char)*(data3++);
8232 (*ptrd++) = (R&0xe0) | ((G>>5)<<2) | (B>>6);
8235 if (ndata!=_data) { _render_resize(ndata,img._width,img._height,(
unsigned char*)_data,_width,_height);
delete[] ndata; }
8238 unsigned short *
const ndata = (img._width==_width && img._height==_height)?(
unsigned short*)_data:
new unsigned short[(
unsigned long)img._width*img._height];
8239 unsigned char *ptrd = (
unsigned char*)ndata;
8240 const
unsigned int M = 248;
8241 switch (img._spectrum) {
8243 if (cimg::X11_attr().byte_order)
for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8244 const unsigned char val = (
unsigned char)*(data1++), G = val>>2;
8245 *(ptrd++) = (val&M) | (G>>3);
8246 *(ptrd++) = (G<<5) | (G>>1);
8247 }
else for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8248 const unsigned char val = (
unsigned char)*(data1++), G = val>>2;
8249 *(ptrd++) = (G<<5) | (G>>1);
8250 *(ptrd++) = (val&M) | (G>>3);
8254 if (cimg::X11_attr().byte_order)
for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8255 const unsigned char G = (
unsigned char)*(data2++)>>2;
8256 *(ptrd++) = ((
unsigned char)*(data1++)&M) | (G>>3);
8258 }
else for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8259 const unsigned char G = (
unsigned char)*(data2++)>>2;
8261 *(ptrd++) = ((
unsigned char)*(data1++)&M) | (G>>3);
8265 if (cimg::X11_attr().byte_order)
for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8266 const unsigned char G = (
unsigned char)*(data2++)>>2;
8267 *(ptrd++) = ((
unsigned char)*(data1++)&M) | (G>>3);
8268 *(ptrd++) = (G<<5) | ((
unsigned char)*(data3++)>>3);
8269 }
else for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8270 const unsigned char G = (
unsigned char)*(data2++)>>2;
8271 *(ptrd++) = (G<<5) | ((
unsigned char)*(data3++)>>3);
8272 *(ptrd++) = ((
unsigned char)*(data1++)&M) | (G>>3);
8275 if (ndata!=_data) { _render_resize(ndata,img._width,img._height,(
unsigned short*)_data,_width,_height);
delete[] ndata; }
8278 unsigned int *
const ndata = (img._width==_width && img._height==_height)?(
unsigned int*)_data:
new unsigned int[(
unsigned long)img._width*img._height];
8279 if (
sizeof(
int)==4) {
8280 unsigned int *ptrd = ndata;
8281 switch (img._spectrum) {
8284 for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8285 const unsigned char val = (
unsigned char)*(data1++);
8286 *(ptrd++) = (val<<16) | (val<<8) | val;
8289 for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8290 const unsigned char val = (
unsigned char)*(data1++);
8291 *(ptrd++) = (val<<16) | (val<<8) | val;
8296 for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy)
8297 *(ptrd++) = ((
unsigned char)*(data1++)<<16) | ((
unsigned char)*(data2++)<<8);
8299 for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy)
8300 *(ptrd++) = ((
unsigned char)*(data2++)<<16) | ((
unsigned char)*(data1++)<<8);
8304 for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy)
8305 *(ptrd++) = ((
unsigned char)*(data1++)<<16) | ((
unsigned char)*(data2++)<<8) | (
unsigned char)*(data3++);
8307 for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy)
8308 *(ptrd++) = ((
unsigned char)*(data3++)<<24) | ((
unsigned char)*(data2++)<<16) | ((
unsigned char)*(data1++)<<8);
8311 unsigned char *ptrd = (
unsigned char*)ndata;
8312 switch (img._spectrum) {
8314 if (cimg::X11_attr().byte_order)
for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8316 *(ptrd++) = (
unsigned char)*(data1++);
8319 }
else for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8322 *(ptrd++) = (
unsigned char)*(data1++);
8327 if (cimg::X11_attr().byte_order)
cimg::swap(data1,data2);
8328 for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8330 *(ptrd++) = (
unsigned char)*(data2++);
8331 *(ptrd++) = (
unsigned char)*(data1++);
8336 if (cimg::X11_attr().byte_order)
for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8338 *(ptrd++) = (
unsigned char)*(data1++);
8339 *(ptrd++) = (
unsigned char)*(data2++);
8340 *(ptrd++) = (
unsigned char)*(data3++);
8341 }
else for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8342 *(ptrd++) = (
unsigned char)*(data3++);
8343 *(ptrd++) = (
unsigned char)*(data2++);
8344 *(ptrd++) = (
unsigned char)*(data1++);
8349 if (ndata!=_data) { _render_resize(ndata,img._width,img._height,(
unsigned int*)_data,_width,_height);
delete[] ndata; }
8353 if (_normalization==3) {
8354 if (cimg::type<T>::is_float()) _min = (float)img.min_max(_max);
8355 else { _min = (float)cimg::type<T>::min(); _max = (float)cimg::type<T>::max(); }
8356 }
else if ((_min>_max) || _normalization==1) _min = (
float)img.min_max(_max);
8357 const float delta = _max - _min, mm = 255/(delta?delta:1.0f);
8358 switch (cimg::X11_attr().nb_bits) {
8360 _set_colormap(_colormap,img._spectrum);
8361 unsigned char *
const ndata = (img._width==_width && img._height==_height)?(
unsigned char*)_data:
new unsigned char[(
unsigned long)img._width*img._height];
8362 unsigned char *ptrd = (
unsigned char*)ndata;
8363 switch (img._spectrum) {
8364 case 1 :
for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8365 const unsigned char R = (
unsigned char)((*(data1++)-_min)*mm);
8368 case 2 :
for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8370 R = (
unsigned char)((*(data1++)-_min)*mm),
8371 G = (
unsigned char)((*(data2++)-_min)*mm);
8372 (*ptrd++) = (R&0xf0) | (G>>4);
8375 for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8377 R = (
unsigned char)((*(data1++)-_min)*mm),
8378 G = (
unsigned char)((*(data2++)-_min)*mm),
8379 B = (
unsigned char)((*(data3++)-_min)*mm);
8380 *(ptrd++) = (R&0xe0) | ((G>>5)<<2) | (B>>6);
8383 if (ndata!=_data) { _render_resize(ndata,img._width,img._height,(
unsigned char*)_data,_width,_height);
delete[] ndata; }
8386 unsigned short *
const ndata = (img._width==_width && img._height==_height)?(
unsigned short*)_data:
new unsigned short[(
unsigned long)img._width*img._height];
8387 unsigned char *ptrd = (
unsigned char*)ndata;
8388 const
unsigned int M = 248;
8389 switch (img._spectrum) {
8391 if (cimg::X11_attr().byte_order)
for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8392 const unsigned char val = (
unsigned char)((*(data1++)-_min)*mm), G = val>>2;
8393 *(ptrd++) = (val&M) | (G>>3);
8394 *(ptrd++) = (G<<5) | (val>>3);
8395 }
else for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8396 const unsigned char val = (
unsigned char)((*(data1++)-_min)*mm), G = val>>2;
8397 *(ptrd++) = (G<<5) | (val>>3);
8398 *(ptrd++) = (val&M) | (G>>3);
8402 if (cimg::X11_attr().byte_order)
for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8403 const unsigned char G = (
unsigned char)((*(data2++)-_min)*mm)>>2;
8404 *(ptrd++) = ((
unsigned char)((*(data1++)-_min)*mm)&M) | (G>>3);
8406 }
else for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8407 const unsigned char G = (
unsigned char)((*(data2++)-_min)*mm)>>2;
8409 *(ptrd++) = ((
unsigned char)((*(data1++)-_min)*mm)&M) | (G>>3);
8413 if (cimg::X11_attr().byte_order)
for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8414 const unsigned char G = (
unsigned char)((*(data2++)-_min)*mm)>>2;
8415 *(ptrd++) = ((
unsigned char)((*(data1++)-_min)*mm)&M) | (G>>3);
8416 *(ptrd++) = (G<<5) | ((
unsigned char)((*(data3++)-_min)*mm)>>3);
8417 }
else for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8418 const unsigned char G = (
unsigned char)((*(data2++)-_min)*mm)>>2;
8419 *(ptrd++) = (G<<5) | ((
unsigned char)((*(data3++)-_min)*mm)>>3);
8420 *(ptrd++) = ((
unsigned char)((*(data1++)-_min)*mm)&M) | (G>>3);
8423 if (ndata!=_data) { _render_resize(ndata,img._width,img._height,(
unsigned short*)_data,_width,_height);
delete[] ndata; }
8426 unsigned int *
const ndata = (img._width==_width && img._height==_height)?(
unsigned int*)_data:
new unsigned int[(
unsigned long)img._width*img._height];
8427 if (
sizeof(
int)==4) {
8428 unsigned int *ptrd = ndata;
8429 switch (img._spectrum) {
8432 for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8433 const unsigned char val = (
unsigned char)((*(data1++)-_min)*mm);
8434 *(ptrd++) = (val<<16) | (val<<8) | val;
8437 for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8438 const unsigned char val = (
unsigned char)((*(data1++)-_min)*mm);
8439 *(ptrd++) = (val<<24) | (val<<16) | (val<<8);
8444 for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy)
8446 ((
unsigned char)((*(data1++)-_min)*mm)<<16) |
8447 ((
unsigned char)((*(data2++)-_min)*mm)<<8);
8449 for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy)
8451 ((
unsigned char)((*(data2++)-_min)*mm)<<16) |
8452 ((
unsigned char)((*(data1++)-_min)*mm)<<8);
8456 for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy)
8458 ((
unsigned char)((*(data1++)-_min)*mm)<<16) |
8459 ((
unsigned char)((*(data2++)-_min)*mm)<<8) |
8460 (
unsigned char)((*(data3++)-_min)*mm);
8462 for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy)
8464 ((
unsigned char)((*(data3++)-_min)*mm)<<24) |
8465 ((
unsigned char)((*(data2++)-_min)*mm)<<16) |
8466 ((
unsigned char)((*(data1++)-_min)*mm)<<8);
8469 unsigned char *ptrd = (
unsigned char*)ndata;
8470 switch (img._spectrum) {
8472 if (cimg::X11_attr().byte_order)
for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8473 const unsigned char val = (
unsigned char)((*(data1++)-_min)*mm);
8478 }
else for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8479 const unsigned char val = (
unsigned char)((*(data1++)-_min)*mm);
8487 if (cimg::X11_attr().byte_order)
cimg::swap(data1,data2);
8488 for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8490 (*ptrd++) = (
unsigned char)((*(data2++)-_min)*mm);
8491 (*ptrd++) = (
unsigned char)((*(data1++)-_min)*mm);
8496 if (cimg::X11_attr().byte_order)
for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8498 (*ptrd++) = (
unsigned char)((*(data1++)-_min)*mm);
8499 (*ptrd++) = (
unsigned char)((*(data2++)-_min)*mm);
8500 (*ptrd++) = (
unsigned char)((*(data3++)-_min)*mm);
8501 }
else for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8502 (*ptrd++) = (
unsigned char)((*(data3++)-_min)*mm);
8503 (*ptrd++) = (
unsigned char)((*(data2++)-_min)*mm);
8504 (*ptrd++) = (
unsigned char)((*(data1++)-_min)*mm);
8509 if (ndata!=_data) { _render_resize(ndata,img._width,img._height,(
unsigned int*)_data,_width,_height);
delete[] ndata; }
8513 XUnlockDisplay(dpy);
8517 template<
typename T>
8520 const unsigned char *ptrs = (
unsigned char*)_data;
8521 img.
assign(_width,_height,1,3);
8523 *data1 = img.data(0,0,0,0),
8524 *data2 = img.data(0,0,0,1),
8525 *data3 = img.data(0,0,0,2);
8526 if (cimg::X11_attr().is_blue_first)
cimg::swap(data1,data3);
8527 switch (cimg::X11_attr().nb_bits) {
8529 for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8530 const unsigned char val = *(ptrs++);
8531 *(data1++) = (T)(val&0xe0);
8532 *(data2++) = (T)((val&0x1c)<<3);
8533 *(data3++) = (T)(val<<6);
8537 if (cimg::X11_attr().byte_order)
for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8538 const unsigned char val0 = *(ptrs++), val1 = *(ptrs++);
8539 *(data1++) = (T)(val0&0xf8);
8540 *(data2++) = (T)((val0<<5) | ((val1&0xe0)>>5));
8541 *(data3++) = (T)(val1<<3);
8542 }
else for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8543 const unsigned short val0 = *(ptrs++), val1 = *(ptrs++);
8544 *(data1++) = (T)(val1&0xf8);
8545 *(data2++) = (T)((val1<<5) | ((val0&0xe0)>>5));
8546 *(data3++) = (T)(val0<<3);
8550 if (cimg::X11_attr().byte_order)
for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8552 *(data1++) = (T)*(ptrs++);
8553 *(data2++) = (T)*(ptrs++);
8554 *(data3++) = (T)*(ptrs++);
8555 }
else for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
8556 *(data3++) = (T)*(ptrs++);
8557 *(data2++) = (T)*(ptrs++);
8558 *(data1++) = (T)*(ptrs++);
8568 #elif cimg_display==2
8570 bool _is_mouse_tracked, _is_cursor_visible;
8571 HANDLE _thread, _is_created, _mutex;
8572 HWND _window, _background_window;
8573 CLIENTCREATESTRUCT _ccs;
8574 unsigned int *_data;
8581 mode.dmSize =
sizeof(DEVMODE);
8582 mode.dmDriverExtra = 0;
8583 EnumDisplaySettings(0,ENUM_CURRENT_SETTINGS,&mode);
8584 return mode.dmPelsWidth;
8589 mode.dmSize =
sizeof(DEVMODE);
8590 mode.dmDriverExtra = 0;
8591 EnumDisplaySettings(0,ENUM_CURRENT_SETTINGS,&mode);
8592 return mode.dmPelsHeight;
8596 WaitForSingleObject(cimg::Win32_attr().wait_event,INFINITE);
8599 static LRESULT APIENTRY _handle_events(HWND window,UINT msg,WPARAM wParam,LPARAM lParam) {
8608 disp->_mouse_x = disp->_mouse_y = -1;
8609 disp->_window_x = disp->_window_y = 0;
8610 disp->set_button().set_key(0).set_key(0,
false)._is_closed =
true;
8611 ReleaseMutex(disp->_mutex);
8612 ShowWindow(disp->_window,SW_HIDE);
8613 disp->_is_event =
true;
8614 SetEvent(cimg::Win32_attr().wait_event);
8617 while (PeekMessage(&st_msg,window,WM_SIZE,WM_SIZE,PM_REMOVE)) {}
8618 WaitForSingleObject(disp->_mutex,INFINITE);
8619 const unsigned int nw = LOWORD(lParam),nh = HIWORD(lParam);
8620 if (nw && nh && (nw!=disp->_width || nh!=disp->_height)) {
8621 disp->_window_width = nw;
8622 disp->_window_height = nh;
8623 disp->_mouse_x = disp->_mouse_y = -1;
8624 disp->_is_resized = disp->_is_event =
true;
8625 SetEvent(cimg::Win32_attr().wait_event);
8627 ReleaseMutex(disp->_mutex);
8630 while (PeekMessage(&st_msg,window,WM_SIZE,WM_SIZE,PM_REMOVE)) {}
8631 WaitForSingleObject(disp->_mutex,INFINITE);
8632 const int nx = (int)(
short)(LOWORD(lParam)), ny = (
int)(short)(HIWORD(lParam));
8633 if (nx!=disp->_window_x || ny!=disp->_window_y) {
8634 disp->_window_x = nx;
8635 disp->_window_y = ny;
8636 disp->_is_moved = disp->_is_event =
true;
8637 SetEvent(cimg::Win32_attr().wait_event);
8639 ReleaseMutex(disp->_mutex);
8645 disp->set_key((
unsigned int)wParam);
8646 SetEvent(cimg::Win32_attr().wait_event);
8649 disp->set_key((
unsigned int)wParam,
false);
8650 SetEvent(cimg::Win32_attr().wait_event);
8652 case WM_MOUSEMOVE : {
8653 while (PeekMessage(&st_msg,window,WM_MOUSEMOVE,WM_MOUSEMOVE,PM_REMOVE)) {}
8654 disp->_mouse_x = LOWORD(lParam);
8655 disp->_mouse_y = HIWORD(lParam);
8656 #if (_WIN32_WINNT>=0x0400) && !defined(NOTRACKMOUSEEVENT)
8657 if (!disp->_is_mouse_tracked) {
8658 TRACKMOUSEEVENT tme;
8659 tme.cbSize =
sizeof(TRACKMOUSEEVENT);
8660 tme.dwFlags = TME_LEAVE;
8661 tme.hwndTrack = disp->_window;
8662 if (TrackMouseEvent(&tme)) disp->_is_mouse_tracked =
true;
8665 if (disp->_mouse_x<0 || disp->_mouse_y<0 || disp->_mouse_x>=disp->width() || disp->_mouse_y>=disp->height())
8666 disp->_mouse_x = disp->_mouse_y = -1;
8667 disp->_is_event =
true;
8668 SetEvent(cimg::Win32_attr().wait_event);
8670 case WM_MOUSELEAVE : {
8671 disp->_mouse_x = disp->_mouse_y = -1;
8672 disp->_is_mouse_tracked =
false;
8674 case WM_LBUTTONDOWN :
8675 disp->set_button(1);
8676 SetEvent(cimg::Win32_attr().wait_event);
8678 case WM_RBUTTONDOWN :
8679 disp->set_button(2);
8680 SetEvent(cimg::Win32_attr().wait_event);
8682 case WM_MBUTTONDOWN :
8683 disp->set_button(3);
8684 SetEvent(cimg::Win32_attr().wait_event);
8687 disp->set_button(1,
false);
8688 SetEvent(cimg::Win32_attr().wait_event);
8691 disp->set_button(2,
false);
8692 SetEvent(cimg::Win32_attr().wait_event);
8695 disp->set_button(3,
false);
8696 SetEvent(cimg::Win32_attr().wait_event);
8699 disp->set_wheel((
int)((
short)HIWORD(wParam))/120);
8700 SetEvent(cimg::Win32_attr().wait_event);
8702 if (disp->_is_cursor_visible) ShowCursor(TRUE);
8703 else ShowCursor(FALSE);
8706 return DefWindowProc(window,msg,wParam,lParam);
8709 static DWORD WINAPI _events_thread(
void* arg) {
8711 const char *
const title = (
const char*)(((
void**)arg)[1]);
8713 delete[] (
void**)arg;
8714 disp->_bmi.bmiHeader.biSize =
sizeof(BITMAPINFOHEADER);
8715 disp->_bmi.bmiHeader.biWidth = disp->width();
8716 disp->_bmi.bmiHeader.biHeight = -disp->height();
8717 disp->_bmi.bmiHeader.biPlanes = 1;
8718 disp->_bmi.bmiHeader.biBitCount = 32;
8719 disp->_bmi.bmiHeader.biCompression = BI_RGB;
8720 disp->_bmi.bmiHeader.biSizeImage = 0;
8721 disp->_bmi.bmiHeader.biXPelsPerMeter = 1;
8722 disp->_bmi.bmiHeader.biYPelsPerMeter = 1;
8723 disp->_bmi.bmiHeader.biClrUsed = 0;
8724 disp->_bmi.bmiHeader.biClrImportant = 0;
8725 disp->_data =
new unsigned int[(
unsigned long)disp->_width*disp->_height];
8726 if (!disp->_is_fullscreen) {
8728 rect.left = rect.top = 0; rect.right = disp->_width-1; rect.bottom = disp->_height-1;
8729 AdjustWindowRect(&rect,WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
false);
8731 border1 = (rect.right - rect.left + 1 - disp->_width)/2,
8732 border2 = rect.bottom - rect.top + 1 - disp->_height - border1;
8733 disp->_window = CreateWindowA(
"MDICLIENT",title?title:
" ",
8734 WS_OVERLAPPEDWINDOW | (disp->_is_closed?0:WS_VISIBLE), CW_USEDEFAULT,CW_USEDEFAULT,
8735 disp->_width + 2*border1, disp->_height + border1 + border2,
8736 0,0,0,&(disp->_ccs));
8737 if (!disp->_is_closed) {
8738 GetWindowRect(disp->_window,&rect);
8739 disp->_window_x = rect.left + border1;
8740 disp->_window_y = rect.top + border2;
8741 }
else disp->_window_x = disp->_window_y = 0;
8744 disp->_window = CreateWindowA(
"MDICLIENT",title?title:
" ",
8745 WS_POPUP | (disp->_is_closed?0:WS_VISIBLE), (sx-disp->_width)/2, (sy-disp->_height)/2,
8746 disp->_width,disp->_height,0,0,0,&(disp->_ccs));
8747 disp->_window_x = disp->_window_y = 0;
8749 SetForegroundWindow(disp->_window);
8750 disp->_hdc = GetDC(disp->_window);
8751 disp->_window_width = disp->_width;
8752 disp->_window_height = disp->_height;
8755 SetWindowLongPtr(disp->_window,GWLP_USERDATA,(LONG_PTR)disp);
8756 SetWindowLongPtr(disp->_window,GWLP_WNDPROC,(LONG_PTR)_handle_events);
8758 SetWindowLong(disp->_window,GWL_USERDATA,(LONG)disp);
8759 SetWindowLong(disp->_window,GWL_WNDPROC,(LONG)_handle_events);
8761 SetEvent(disp->_is_created);
8762 while (GetMessage(&msg,0,0,0)) DispatchMessage(&msg);
8767 if (_is_closed) _window_x = _window_y = -1;
8770 rect.left = rect.top = 0; rect.right = _width-1; rect.bottom = _height-1;
8771 AdjustWindowRect(&rect,WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
false);
8773 border1 = (rect.right - rect.left + 1 - _width)/2,
8774 border2 = rect.bottom - rect.top + 1 - _height - border1;
8775 GetWindowRect(_window,&rect);
8776 _window_x = rect.left + border1;
8777 _window_y = rect.top + border2;
8782 void _init_fullscreen() {
8783 _background_window = 0;
8784 if (!_is_fullscreen || _is_closed) _curr_mode.dmSize = 0;
8787 unsigned int imode = 0, ibest = 0, bestbpp = 0, bw = ~0U, bh = ~0U;
8788 for (mode.dmSize =
sizeof(DEVMODE), mode.dmDriverExtra = 0; EnumDisplaySettings(0,imode,&mode); ++imode) {
8789 const unsigned int nw = mode.dmPelsWidth, nh = mode.dmPelsHeight;
8790 if (nw>=_width && nh>=_height && mode.dmBitsPerPel>=bestbpp && nw<=bw && nh<=bh) {
8791 bestbpp = mode.dmBitsPerPel;
8797 _curr_mode.dmSize =
sizeof(DEVMODE); _curr_mode.dmDriverExtra = 0;
8798 EnumDisplaySettings(0,ENUM_CURRENT_SETTINGS,&_curr_mode);
8799 EnumDisplaySettings(0,ibest,&mode);
8800 ChangeDisplaySettings(&mode,0);
8801 }
else _curr_mode.dmSize = 0;
8804 if (sx!=_width || sy!=_height) {
8805 CLIENTCREATESTRUCT background_ccs;
8806 _background_window = CreateWindowA(
"MDICLIENT",
"",WS_POPUP | WS_VISIBLE, 0,0,sx,sy,0,0,0,&background_ccs);
8807 SetForegroundWindow(_background_window);
8812 void _desinit_fullscreen() {
8813 if (!_is_fullscreen)
return;
8814 if (_background_window) DestroyWindow(_background_window);
8815 _background_window = 0;
8816 if (_curr_mode.dmSize) ChangeDisplaySettings(&_curr_mode,0);
8817 _is_fullscreen =
false;
8820 CImgDisplay& _assign(
const unsigned int dimw,
const unsigned int dimh,
const char *
const ptitle=0,
8821 const unsigned int normalization_type=3,
8822 const bool fullscreen_flag=
false,
const bool closed_flag=
false) {
8825 const char *
const nptitle = ptitle?ptitle:
"";
8826 const unsigned int s = (
unsigned int)std::strlen(nptitle) + 1;
8827 char *
const tmp_title = s?
new char[s]:0;
8828 if (s) std::memcpy(tmp_title,nptitle,s*
sizeof(
char));
8836 _normalization = normalization_type<4?normalization_type:3;
8837 _is_fullscreen = fullscreen_flag;
8838 _window_x = _window_y = 0;
8839 _is_closed = closed_flag;
8840 _is_cursor_visible =
true;
8841 _is_mouse_tracked =
false;
8844 if (_is_fullscreen) _init_fullscreen();
8847 void *
const arg = (
void*)(
new void*[2]);
8848 ((
void**)arg)[0] = (
void*)
this;
8849 ((
void**)arg)[1] = (
void*)_title;
8850 unsigned long ThreadID = 0;
8851 _mutex = CreateMutex(0,FALSE,0);
8852 _is_created = CreateEvent(0,FALSE,FALSE,0);
8853 _thread = CreateThread(0,0,_events_thread,arg,0,&ThreadID);
8854 WaitForSingleObject(_is_created,INFINITE);
8860 DestroyWindow(_window);
8861 TerminateThread(_thread,0);
8866 if (_is_fullscreen) _desinit_fullscreen();
8867 _width = _height = _normalization = _window_width = _window_height = 0;
8868 _window_x = _window_y = 0;
8869 _is_fullscreen =
false;
8877 CImgDisplay&
assign(
const unsigned int dimw,
const unsigned int dimh,
const char *
const title=0,
8878 const unsigned int normalization_type=3,
8879 const bool fullscreen_flag=
false,
const bool closed_flag=
false) {
8880 if (!dimw || !dimh)
return assign();
8881 _assign(dimw,dimh,title,normalization_type,fullscreen_flag,closed_flag);
8883 std::memset(_data,0,
sizeof(
unsigned int)*_width*_height);
8887 template<
typename T>
8889 const unsigned int normalization_type=3,
8890 const bool fullscreen_flag=
false,
const bool closed_flag=
false) {
8891 if (!img)
return assign();
8893 const CImg<T>& nimg = (img._depth==1)?img:(tmp=img.get_projections2d(img._width/2,img._height/2,img._depth/2));
8894 _assign(nimg._width,nimg._height,title,normalization_type,fullscreen_flag,closed_flag);
8895 if (_normalization==2) _min = (float)nimg.min_max(_max);
8899 template<
typename T>
8901 const unsigned int normalization_type=3,
8902 const bool fullscreen_flag=
false,
const bool closed_flag=
false) {
8903 if (!list)
return assign();
8905 const CImg<T> img = list>
'x', &nimg = (img._depth==1)?img:(tmp=img.get_projections2d(img._width/2,img._height/2,img._depth/2));
8906 _assign(nimg._width,nimg._height,title,normalization_type,fullscreen_flag,closed_flag);
8907 if (_normalization==2) _min = (float)nimg.min_max(_max);
8912 if (!disp)
return assign();
8913 _assign(disp._width,disp._height,disp._title,disp._normalization,disp._is_fullscreen,disp._is_closed);
8914 std::memcpy(_data,disp._data,
sizeof(
unsigned int)*_width*_height);
8918 CImgDisplay&
resize(
const int nwidth,
const int nheight,
const bool force_redraw=
true) {
8919 if (!nwidth || !nheight || (
is_empty() && (nwidth<0 || nheight<0)))
return assign();
8922 tmpdimx = (nwidth>0)?nwidth:(-nwidth*_width/100),
8923 tmpdimy = (nheight>0)?nheight:(-nheight*_height/100),
8924 dimx = tmpdimx?tmpdimx:1,
8925 dimy = tmpdimy?tmpdimy:1;
8926 if (_window_width!=dimx || _window_height!=dimy) {
8927 RECT rect; rect.left = rect.top = 0; rect.right = dimx - 1; rect.bottom = dimy - 1;
8928 AdjustWindowRect(&rect,WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
false);
8929 const int cwidth = rect.right - rect.left + 1, cheight = rect.bottom - rect.top + 1;
8930 SetWindowPos(_window,0,0,0,cwidth,cheight,SWP_NOMOVE | SWP_NOZORDER | SWP_NOCOPYBITS);
8932 if (_width!=dimx || _height!=dimy) {
8933 unsigned int *
const ndata =
new unsigned int[dimx*dimy];
8934 if (force_redraw) _render_resize(_data,_width,_height,ndata,dimx,dimy);
8935 else std::memset(ndata,0x80,
sizeof(
unsigned int)*dimx*dimy);
8938 _bmi.bmiHeader.biWidth = dimx;
8939 _bmi.bmiHeader.biHeight = -(int)dimy;
8943 _window_width = dimx; _window_height = dimy;
8944 _is_resized =
false;
8946 if (force_redraw)
return paint();
8953 const unsigned long buf_size = _width*_height*4UL;
8954 void *odata = std::malloc(buf_size);
8955 std::memcpy(odata,_data,buf_size);
8956 assign(_width,_height,_title,_normalization,!_is_fullscreen,
false);
8957 std::memcpy(_data,odata,buf_size);
8961 return assign(_width,_height,_title,_normalization,!_is_fullscreen,
false);
8965 if (
is_empty() || !_is_closed)
return *
this;
8967 if (_is_fullscreen) _init_fullscreen();
8968 ShowWindow(_window,SW_SHOW);
8969 _update_window_pos();
8974 if (
is_empty() || _is_closed)
return *
this;
8976 if (_is_fullscreen) _desinit_fullscreen();
8977 ShowWindow(_window,SW_HIDE);
8978 _window_x = _window_y = 0;
8984 if (!_is_fullscreen) {
8985 RECT rect; rect.left = rect.top = 0; rect.right = _window_width-1; rect.bottom = _window_height-1;
8986 AdjustWindowRect(&rect,WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
false);
8987 const int border1 = (rect.right-rect.left+1-_width)/2, border2 = rect.bottom-rect.top+1-_height-border1;
8988 SetWindowPos(_window,0,posx-border1,posy-border2,0,0,SWP_NOSIZE | SWP_NOZORDER);
8989 }
else SetWindowPos(_window,0,posx,posy,0,0,SWP_NOSIZE | SWP_NOZORDER);
8998 _is_cursor_visible =
true;
9000 SendMessage(_window,WM_SETCURSOR,0,0);
9006 _is_cursor_visible =
false;
9008 SendMessage(_window,WM_SETCURSOR,0,0);
9013 if (_is_closed || posx<0 || posy<0)
return *
this;
9014 _update_window_pos();
9015 const int res = (int)SetCursorPos(_window_x + posx,_window_y + posy);
9016 if (res) { _mouse_x = posx; _mouse_y = posy; }
9022 char tmp[1024] = { 0 };
9024 va_start(ap, format);
9025 cimg_vsnprintf(tmp,
sizeof(tmp),format,ap);
9027 if (!std::strcmp(_title,tmp))
return *
this;
9029 const unsigned int s = (
unsigned int)std::strlen(tmp) + 1;
9030 _title =
new char[s];
9031 std::memcpy(_title,tmp,s*
sizeof(
char));
9032 SetWindowTextA(_window, tmp);
9036 template<
typename T>
9039 throw CImgArgumentException(_cimgdisplay_instance
9040 "display(): Empty specified image.",
9041 cimgdisplay_instance);
9047 if (_is_closed)
return *
this;
9048 WaitForSingleObject(_mutex,INFINITE);
9049 SetDIBitsToDevice(_hdc,0,0,_width,_height,0,0,0,_height,_data,&_bmi,DIB_RGB_COLORS);
9050 ReleaseMutex(_mutex);
9054 template<
typename T>
9057 throw CImgArgumentException(_cimgdisplay_instance
9058 "render(): Empty specified image.",
9059 cimgdisplay_instance);
9062 if (img._depth!=1)
return render(img.get_projections2d(img._width/2,img._height/2,img._depth/2));
9066 *data2 = (img._spectrum>=2)?img.data(0,0,0,1):data1,
9067 *data3 = (img._spectrum>=3)?img.data(0,0,0,2):data1;
9069 WaitForSingleObject(_mutex,INFINITE);
9071 *
const ndata = (img._width==_width && img._height==_height)?_data:
new unsigned int[(
unsigned long)img._width*img._height],
9074 if (!_normalization || (_normalization==3 && cimg::type<T>::string()==cimg::type<unsigned char>::string())) {
9076 switch (img._spectrum) {
9078 for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
9079 const unsigned char val = (
unsigned char)*(data1++);
9080 *(ptrd++) = (val<<16) | (val<<8) | val;
9084 for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy)
9085 *(ptrd++) = ((
unsigned char)*(data1++)<<16) | ((
unsigned char)*(data2++)<<8);
9088 for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy)
9089 *(ptrd++) = ((
unsigned char)*(data1++)<<16) | ((
unsigned char)*(data2++)<<8) | (
unsigned char)*(data3++);
9093 if (_normalization==3) {
9094 if (cimg::type<T>::is_float()) _min = (
float)img.min_max(_max);
9095 else { _min = (float)cimg::type<T>::min(); _max = (float)cimg::type<T>::max(); }
9096 }
else if ((_min>_max) || _normalization==1) _min = (
float)img.min_max(_max);
9097 const float delta = _max - _min, mm = 255/(delta?delta:1.0f);
9098 switch (img._spectrum) {
9100 for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
9101 const unsigned char val = (
unsigned char)((*(data1++)-_min)*mm);
9102 *(ptrd++) = (val<<16) | (val<<8) | val;
9106 for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
9108 R = (
unsigned char)((*(data1++)-_min)*mm),
9109 G = (
unsigned char)((*(data2++)-_min)*mm);
9110 *(ptrd++) = (R<<16) | (G<<8);
9114 for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
9116 R = (
unsigned char)((*(data1++)-_min)*mm),
9117 G = (
unsigned char)((*(data2++)-_min)*mm),
9118 B = (
unsigned char)((*(data3++)-_min)*mm);
9119 *(ptrd++) = (R<<16) | (G<<8) | B;
9124 if (ndata!=_data) { _render_resize(ndata,img._width,img._height,_data,_width,_height);
delete[] ndata; }
9125 ReleaseMutex(_mutex);
9129 template<
typename T>
9132 const unsigned int *ptrs = _data;
9133 img.
assign(_width,_height,1,3);
9135 *data1 = img.data(0,0,0,0),
9136 *data2 = img.data(0,0,0,1),
9137 *data3 = img.data(0,0,0,2);
9138 for (
unsigned long xy = (
unsigned long)img._width*img._height; xy>0; --xy) {
9139 const unsigned int val = *(ptrs++);
9140 *(data1++) = (T)(
unsigned char)(val>>16);
9141 *(data2++) = (T)(
unsigned char)((val>>8)&0xFF);
9142 *(data3++) = (T)(
unsigned char)(val&0xFF);
9254 template<
typename T>
9257 unsigned int _width, _height, _depth, _spectrum;
9303 typedef typename cimg::superset<T,bool>::type Tbool;
9304 typedef typename cimg::superset<T,unsigned char>::type Tuchar;
9305 typedef typename cimg::superset<T,char>::type Tchar;
9306 typedef typename cimg::superset<T,unsigned short>::type Tushort;
9307 typedef typename cimg::superset<T,short>::type Tshort;
9308 typedef typename cimg::superset<T,unsigned int>::type Tuint;
9309 typedef typename cimg::superset<T,int>::type Tint;
9310 typedef typename cimg::superset<T,unsigned long>::type Tulong;
9311 typedef typename cimg::superset<T,long>::type Tlong;
9312 typedef typename cimg::superset<T,float>::type Tfloat;
9313 typedef typename cimg::superset<T,double>::type Tdouble;
9314 typedef typename cimg::last<T,bool>::type boolT;
9315 typedef typename cimg::last<T,unsigned char>::type ucharT;
9316 typedef typename cimg::last<T,char>::type charT;
9317 typedef typename cimg::last<T,unsigned short>::type ushortT;
9318 typedef typename cimg::last<T,short>::type shortT;
9319 typedef typename cimg::last<T,unsigned int>::type uintT;
9320 typedef typename cimg::last<T,int>::type intT;
9321 typedef typename cimg::last<T,unsigned long>::type ulongT;
9322 typedef typename cimg::last<T,long>::type longT;
9323 typedef typename cimg::last<T,float>::type floatT;
9324 typedef typename cimg::last<T,double>::type doubleT;
9333 #include cimg_plugin
9336 #include cimg_plugin1
9339 #include cimg_plugin2
9342 #include cimg_plugin3
9345 #include cimg_plugin4
9348 #include cimg_plugin5
9351 #include cimg_plugin6
9354 #include cimg_plugin7
9357 #include cimg_plugin8
9377 if (!_is_shared)
delete[] _data;
9396 CImg():_width(0),_height(0),_depth(0),_spectrum(0),_is_shared(false),_data(0) {}
9418 explicit CImg(
const unsigned int size_x,
const unsigned int size_y=1,
const unsigned int size_z=1,
const unsigned int size_c=1):
9420 const unsigned long siz = (
unsigned long)size_x*size_y*size_z*size_c;
9422 _width = size_x; _height = size_y; _depth = size_z; _spectrum = size_c;
9423 try { _data =
new T[siz]; }
catch (...) {
9424 _width = _height = _depth = _spectrum = 0; _data = 0;
9426 "CImg(): Failed to allocate memory (%s) for image (%u,%u,%u,%u).",
9428 cimg::strbuffersize(
sizeof(T)*size_x*size_y*size_z*size_c),size_x,size_y,size_z,size_c);
9430 }
else { _width = _height = _depth = _spectrum = 0; _data = 0; }
9447 CImg(
const unsigned int size_x,
const unsigned int size_y,
const unsigned int size_z,
const unsigned int size_c,
const T value):
9449 const unsigned long siz = (
unsigned long)size_x*size_y*size_z*size_c;
9451 _width = size_x; _height = size_y; _depth = size_z; _spectrum = size_c;
9452 try { _data =
new T[siz]; }
catch (...) {
9453 _width = _height = _depth = _spectrum = 0; _data = 0;
9455 "CImg(): Failed to allocate memory (%s) for image (%u,%u,%u,%u).",
9457 cimg::strbuffersize(
sizeof(T)*size_x*size_y*size_z*size_c),size_x,size_y,size_z,size_c);
9460 }
else { _width = _height = _depth = _spectrum = 0; _data = 0; }
9490 CImg(
const unsigned int size_x,
const unsigned int size_y,
const unsigned int size_z,
const unsigned int size_c,
9491 const int value0,
const int value1, ...):_width(0),_height(0),_depth(0),_spectrum(0),_is_shared(false),_data(0) {
9492 #define _CImg_stdarg(img,a0,a1,N,t) { \
9493 unsigned long _siz = (unsigned long)N; \
9497 T *ptrd = (img)._data; \
9498 *(ptrd++) = (T)a0; \
9500 *(ptrd++) = (T)a1; \
9501 for (; _siz; --_siz) *(ptrd++) = (T)va_arg(ap,t); \
9506 assign(size_x,size_y,size_z,size_c);
9507 _CImg_stdarg(*
this,value0,value1,(
unsigned long)size_x*size_y*size_z*size_c,
int);
9532 CImg(
const unsigned int size_x,
const unsigned int size_y,
const unsigned int size_z,
const unsigned int size_c,
9533 const double value0,
const double value1, ...):_width(0),_height(0),_depth(0),_spectrum(0),_is_shared(false),_data(0) {
9534 assign(size_x,size_y,size_z,size_c);
9535 _CImg_stdarg(*
this,value0,value1,(
unsigned long)size_x*size_y*size_z*size_c,
double);
9566 CImg(
const unsigned int size_x,
const unsigned int size_y,
const unsigned int size_z,
const unsigned int size_c,
9567 const char *
const values,
const bool repeat_values):_is_shared(false) {
9568 const unsigned long siz = (
unsigned long)size_x*size_y*size_z*size_c;
9570 _width = size_x; _height = size_y; _depth = size_z; _spectrum = size_c;
9571 try { _data =
new T[siz]; }
catch (...) {
9572 _width = _height = _depth = _spectrum = 0; _data = 0;
9574 "CImg(): Failed to allocate memory (%s) for image (%u,%u,%u,%u).",
9576 cimg::strbuffersize(
sizeof(T)*size_x*size_y*size_z*size_c),size_x,size_y,size_z,size_c);
9578 fill(values,repeat_values);
9579 }
else { _width = _height = _depth = _spectrum = 0; _data = 0; }
9609 template<
typename t>
9610 CImg(
const t *
const values,
const unsigned int size_x,
const unsigned int size_y=1,
9611 const unsigned int size_z=1,
const unsigned int size_c=1,
const bool is_shared=
false):_is_shared(false) {
9613 _width = _height = _depth = _spectrum = 0; _data = 0;
9615 "CImg(): Invalid construction request of a (%u,%u,%u,%u) shared instance from a (%s*) buffer "
9616 "(pixel types are different).",
9620 const unsigned long siz = (
unsigned long)size_x*size_y*size_z*size_c;
9621 if (values && siz) {
9622 _width = size_x; _height = size_y; _depth = size_z; _spectrum = size_c;
9623 try { _data =
new T[siz]; }
catch (...) {
9624 _width = _height = _depth = _spectrum = 0; _data = 0;
9626 "CImg(): Failed to allocate memory (%s) for image (%u,%u,%u,%u).",
9628 cimg::strbuffersize(
sizeof(T)*size_x*size_y*size_z*size_c),size_x,size_y,size_z,size_c);
9631 const t *ptrs = values; cimg_for(*
this,ptrd,T) *ptrd = (T)*(ptrs++);
9632 }
else { _width = _height = _depth = _spectrum = 0; _data = 0; }
9636 CImg(
const T *
const values,
const unsigned int size_x,
const unsigned int size_y=1,
9637 const unsigned int size_z=1,
const unsigned int size_c=1,
const bool is_shared=
false) {
9638 const unsigned long siz = (
unsigned long)size_x*size_y*size_z*size_c;
9639 if (values && siz) {
9640 _width = size_x; _height = size_y; _depth = size_z; _spectrum = size_c; _is_shared =
is_shared;
9641 if (_is_shared) _data =
const_cast<T*
>(values);
9643 try { _data =
new T[siz]; }
catch (...) {
9644 _width = _height = _depth = _spectrum = 0; _data = 0;
9646 "CImg(): Failed to allocate memory (%s) for image (%u,%u,%u,%u).",
9648 cimg::strbuffersize(
sizeof(T)*size_x*size_y*size_z*size_c),size_x,size_y,size_z,size_c);
9650 std::memcpy(_data,values,siz*
sizeof(T)); }
9651 }
else { _width = _height = _depth = _spectrum = 0; _is_shared =
false; _data = 0; }
9673 explicit CImg(
const char *
const filename):_width(0),_height(0),_depth(0),_spectrum(0),_is_shared(false),_data(0) {
9692 template<
typename t>
9694 const unsigned long siz = img.size();
9695 if (img._data && siz) {
9696 _width = img._width; _height = img._height; _depth = img._depth; _spectrum = img._spectrum;
9697 try { _data =
new T[siz]; }
catch (...) {
9698 _width = _height = _depth = _spectrum = 0; _data = 0;
9700 "CImg(): Failed to allocate memory (%s) for image (%u,%u,%u,%u).",
9702 cimg::strbuffersize(
sizeof(T)*img._width*img._height*img._depth*img._spectrum),
9703 img._width,img._height,img._depth,img._spectrum);
9705 const t *ptrs = img._data; cimg_for(*
this,ptrd,T) *ptrd = (T)*(ptrs++);
9706 }
else { _width = _height = _depth = _spectrum = 0; _data = 0; }
9711 const unsigned long siz = img.size();
9712 if (img._data && siz) {
9713 _width = img._width; _height = img._height; _depth = img._depth; _spectrum = img._spectrum; _is_shared = img._is_shared;
9714 if (_is_shared) _data =
const_cast<T*
>(img._data);
9716 try { _data =
new T[siz]; }
catch (...) {
9717 _width = _height = _depth = _spectrum = 0; _data = 0;
9719 "CImg(): Failed to allocate memory (%s) for image (%u,%u,%u,%u).",
9721 cimg::strbuffersize(
sizeof(T)*img._width*img._height*img._depth*img._spectrum),
9722 img._width,img._height,img._depth,img._spectrum);
9725 std::memcpy(_data,img._data,siz*
sizeof(T));
9727 }
else { _width = _height = _depth = _spectrum = 0; _is_shared =
false; _data = 0; }
9745 template<
typename t>
9748 _width = _height = _depth = _spectrum = 0; _data = 0;
9750 "CImg(): Invalid construction request of a shared instance from a "
9751 "CImg<%s> image (%u,%u,%u,%u,%p) (pixel types are different).",
9755 const unsigned long siz = img.size();
9756 if (img._data && siz) {
9757 _width = img._width; _height = img._height; _depth = img._depth; _spectrum = img._spectrum;
9758 try { _data =
new T[siz]; }
catch (...) {
9759 _width = _height = _depth = _spectrum = 0; _data = 0;
9761 "CImg(): Failed to allocate memory (%s) for image (%u,%u,%u,%u).",
9763 cimg::strbuffersize(
sizeof(T)*img._width*img._height*img._depth*img._spectrum),
9764 img._width,img._height,img._depth,img._spectrum);
9766 const t *ptrs = img._data; cimg_for(*
this,ptrd,T) *ptrd = (T)*(ptrs++);
9767 }
else { _width = _height = _depth = _spectrum = 0; _data = 0; }
9772 const unsigned long siz = img.size();
9773 if (img._data && siz) {
9774 _width = img._width; _height = img._height; _depth = img._depth; _spectrum = img._spectrum; _is_shared =
is_shared;
9775 if (_is_shared) _data =
const_cast<T*
>(img._data);
9777 try { _data =
new T[siz]; }
catch (...) {
9778 _width = _height = _depth = _spectrum = 0; _data = 0;
9780 "CImg(): Failed to allocate memory (%s) for image (%u,%u,%u,%u).",
9782 cimg::strbuffersize(
sizeof(T)*img._width*img._height*img._depth*img._spectrum),
9783 img._width,img._height,img._depth,img._spectrum);
9785 std::memcpy(_data,img._data,siz*
sizeof(T));
9787 }
else { _width = _height = _depth = _spectrum = 0; _is_shared =
false; _data = 0; }
9808 template<
typename t>
9809 CImg(
const CImg<t>& img,
const char *
const dimensions):_width(0),_height(0),_depth(0),_spectrum(0),_is_shared(false),_data(0) {
9823 template<
typename t>
9824 CImg(
const CImg<t>& img,
const char *
const dimensions,
const T value):
9825 _width(0),_height(0),_depth(0),_spectrum(0),_is_shared(false),_data(0) {
9826 assign(img,dimensions).fill(value);
9838 explicit CImg(
const CImgDisplay &disp):_width(0),_height(0),_depth(0),_spectrum(0),_is_shared(false),_data(0) {
9847 if (!_is_shared)
delete[] _data;
9848 _width = _height = _depth = _spectrum = 0; _is_shared =
false; _data = 0;
9856 CImg<T>&
assign(
const unsigned int size_x,
const unsigned int size_y=1,
const unsigned int size_z=1,
const unsigned int size_c=1) {
9857 const unsigned long siz = (
unsigned long)size_x*size_y*size_z*size_c;
9858 if (!siz)
return assign();
9859 const unsigned long curr_siz =
size();
9860 if (siz!=curr_siz) {
9863 "assign(): Invalid assignement request of shared instance from specified image (%u,%u,%u,%u).",
9865 size_x,size_y,size_z,size_c);
9868 try { _data =
new T[siz]; }
catch (...) {
9869 _width = _height = _depth = _spectrum = 0; _data = 0;
9871 "assign(): Failed to allocate memory (%s) for image (%u,%u,%u,%u).",
9873 cimg::strbuffersize(
sizeof(T)*size_x*size_y*size_z*size_c),size_x,size_y,size_z,size_c);
9877 _width = size_x; _height = size_y; _depth = size_z; _spectrum = size_c;
9885 CImg<T>&
assign(
const unsigned int size_x,
const unsigned int size_y,
const unsigned int size_z,
const unsigned int size_c,
const T value) {
9886 return assign(size_x,size_y,size_z,size_c).fill(value);
9893 CImg<T>&
assign(
const unsigned int size_x,
const unsigned int size_y,
const unsigned int size_z,
const unsigned int size_c,
9894 const int value0,
const int value1, ...) {
9895 assign(size_x,size_y,size_z,size_c);
9896 _CImg_stdarg(*
this,value0,value1,(
unsigned long)size_x*size_y*size_z*size_c,
int);
9904 CImg<T>&
assign(
const unsigned int size_x,
const unsigned int size_y,
const unsigned int size_z,
const unsigned int size_c,
9905 const double value0,
const double value1, ...) {
9906 assign(size_x,size_y,size_z,size_c);
9907 _CImg_stdarg(*
this,value0,value1,(
unsigned long)size_x*size_y*size_z*size_c,
double);
9915 CImg<T>&
assign(
const unsigned int size_x,
const unsigned int size_y,
const unsigned int size_z,
const unsigned int size_c,
9916 const char *
const values,
const bool repeat_values) {
9917 return assign(size_x,size_y,size_z,size_c).fill(values,repeat_values);
9924 template<
typename t>
9925 CImg<T>&
assign(
const t *
const values,
const unsigned int size_x,
const unsigned int size_y=1,
9926 const unsigned int size_z=1,
const unsigned int size_c=1) {
9927 const unsigned long siz = (
unsigned long)size_x*size_y*size_z*size_c;
9928 if (!values || !siz)
return assign();
9929 assign(size_x,size_y,size_z,size_c);
9930 const t *ptrs = values; cimg_for(*
this,ptrd,T) *ptrd = (T)*(ptrs++);
9935 CImg<T>&
assign(
const T *
const values,
const unsigned int size_x,
const unsigned int size_y=1,
9936 const unsigned int size_z=1,
const unsigned int size_c=1) {
9937 const unsigned long siz = (
unsigned long)size_x*size_y*size_z*size_c;
9938 if (!values || !siz)
return assign();
9939 const unsigned long curr_siz =
size();
9940 if (values==_data && siz==curr_siz)
return assign(size_x,size_y,size_z,size_c);
9941 if (_is_shared || values+siz<_data || values>=_data+
size()) {
9942 assign(size_x,size_y,size_z,size_c);
9943 if (_is_shared) std::memmove(_data,values,siz*
sizeof(T));
9944 else std::memcpy(_data,values,siz*
sizeof(T));
9947 try { new_data =
new T[siz]; }
catch (...) {
9948 _width = _height = _depth = _spectrum = 0; _data = 0;
9950 "assign(): Failed to allocate memory (%s) for image (%u,%u,%u,%u).",
9952 cimg::strbuffersize(
sizeof(T)*size_x*size_y*size_z*size_c),size_x,size_y,size_z,size_c);
9954 std::memcpy(new_data,values,siz*
sizeof(T));
9955 delete[] _data; _data = new_data; _width = size_x; _height = size_y; _depth = size_z; _spectrum = size_c;
9961 template<
typename t>
9962 CImg<T>&
assign(
const t *
const values,
const unsigned int size_x,
const unsigned int size_y,
9963 const unsigned int size_z,
const unsigned int size_c,
const bool is_shared) {
9966 "assign(): Invalid assignment request of shared instance from (%s*) buffer"
9967 "(pixel types are different).",
9970 return assign(values,size_x,size_y,size_z,size_c);
9974 CImg<T>&
assign(
const T *
const values,
const unsigned int size_x,
const unsigned int size_y,
9975 const unsigned int size_z,
const unsigned int size_c,
const bool is_shared) {
9976 const unsigned long siz = (
unsigned long)size_x*size_y*size_z*size_c;
9977 if (!values || !siz) {
9980 "assign(): Invalid assignment request of shared instance from (null) or empty buffer.",
9984 if (!is_shared) {
if (_is_shared)
assign();
assign(values,size_x,size_y,size_z,size_c); }
9987 if (values+siz<_data || values>=_data+
size())
assign();
9989 "assign(): Shared image instance has overlapping memory.",
9992 _width = size_x; _height = size_y; _depth = size_z; _spectrum = size_c; _is_shared =
true;
9993 _data =
const_cast<T*
>(values);
10003 return load(filename);
10010 template<
typename t>
10012 return assign(img._data,img._width,img._height,img._depth,img._spectrum);
10019 template<
typename t>
10021 return assign(img._data,img._width,img._height,img._depth,img._spectrum,is_shared);
10028 template<
typename t>
10030 if (!dimensions || !*dimensions)
return assign(img._width,img._height,img._depth,img._spectrum);
10031 unsigned int siz[4] = { 0,1,1,1 }, k = 0;
10032 for (
const char *s = dimensions; *s && k<4; ++k) {
10033 char item[256] = { 0 };
10034 if (std::sscanf(s,
"%255[^0-9%xyzvwhdcXYZVWHDC]",item)>0) s+=std::strlen(item);
10036 unsigned int val = 0;
char sep = 0;
10037 if (std::sscanf(s,
"%u%c",&val,&sep)>0) {
10038 if (sep==
'%') siz[k] = val*(k==0?_width:k==1?_height:k==2?_depth:_spectrum)/100;
10040 while (*s>=
'0' && *s<=
'9') ++s;
if (sep==
'%') ++s;
10042 case 'x' :
case 'w' : siz[k] = img._width; ++s;
break;
10043 case 'y' :
case 'h' : siz[k] = img._height; ++s;
break;
10044 case 'z' :
case 'd' : siz[k] = img._depth; ++s;
break;
10045 case 'c' :
case 's' : siz[k] = img._spectrum; ++s;
break;
10048 "assign(): Invalid character '%c' detected in specified dimension string '%s'.",
10054 return assign(siz[0],siz[1],siz[2],siz[3]);
10061 template<
typename t>
10063 return assign(img,dimensions).fill(value);
10101 template<
typename t>
10110 if (_is_shared || img._is_shared) img.assign(*
this);
10134 template<
typename t>
10136 const unsigned int npos = pos>list._width?list._width:pos;
10174 return _empty.assign();
10214 #if cimg_verbosity>=3
10215 T&
operator()(
const unsigned int x,
const unsigned int y=0,
const unsigned int z=0,
const unsigned int c=0) {
10216 const unsigned long off = (
unsigned long)
offset(x,y,z,c);
10217 if (!_data || off>=
size()) {
10219 "operator(): Invalid pixel request, at coordinates (%u,%u,%u,%u) [offset=%u].",
10224 else return _data[off];
10228 const T&
operator()(
const unsigned int x,
const unsigned int y=0,
const unsigned int z=0,
const unsigned int c=0)
const {
10229 return const_cast<CImg<T>*
>(
this)->
operator()(x,y,z,c);
10245 T&
operator()(
const unsigned int x,
const unsigned int y,
const unsigned int z,
const unsigned int c,
10246 const unsigned long wh,
const unsigned long whd=0) {
10248 return (*
this)(x,y,z,c);
10252 const T&
operator()(
const unsigned int x,
const unsigned int y,
const unsigned int z,
const unsigned int c,
10253 const unsigned long wh,
const unsigned long whd=0)
const {
10255 return (*
this)(x,y,z,c);
10262 const T&
operator()(
const unsigned int x)
const {
10266 T&
operator()(
const unsigned int x,
const unsigned int y) {
10267 return _data[x + y*_width];
10270 const T&
operator()(
const unsigned int x,
const unsigned int y)
const {
10271 return _data[x + y*_width];
10274 T&
operator()(
const unsigned int x,
const unsigned int y,
const unsigned int z) {
10275 return _data[x + y*(
unsigned long)_width + z*(
unsigned long)_width*_height];
10278 const T&
operator()(
const unsigned int x,
const unsigned int y,
const unsigned int z)
const {
10279 return _data[x + y*(
unsigned long)_width + z*(
unsigned long)_width*_height];
10282 T&
operator()(
const unsigned int x,
const unsigned int y,
const unsigned int z,
const unsigned int c) {
10283 return _data[x + y*(
unsigned long)_width + z*(
unsigned long)_width*_height + c*(
unsigned long)_width*_height*_depth];
10286 const T&
operator()(
const unsigned int x,
const unsigned int y,
const unsigned int z,
const unsigned int c)
const {
10287 return _data[x + y*(
unsigned long)_width + z*(
unsigned long)_width*_height + c*(
unsigned long)_width*_height*_depth];
10290 T&
operator()(
const unsigned int x,
const unsigned int y,
const unsigned int z,
const unsigned int,
10291 const unsigned long wh) {
10292 return _data[x + y*_width + z*wh];
10295 const T&
operator()(
const unsigned int x,
const unsigned int y,
const unsigned int z,
const unsigned int,
10296 const unsigned long wh)
const {
10297 return _data[x + y*_width + z*wh];
10300 T&
operator()(
const unsigned int x,
const unsigned int y,
const unsigned int z,
const unsigned int c,
10301 const unsigned long wh,
const unsigned long whd) {
10302 return _data[x + y*_width + z*wh + c*whd];
10305 const T&
operator()(
const unsigned int x,
const unsigned int y,
const unsigned int z,
const unsigned int c,
10306 const unsigned long wh,
const unsigned long whd)
const {
10307 return _data[x + y*_width + z*wh + c*whd];
10338 operator const T*()
const {
10357 return fill(value);
10384 fill(expression,
true);
10397 template<
typename t>
10441 template<
typename t>
10443 cimg_for(*
this,ptrd,T) *ptrd = (T)(*ptrd + value);
10459 const CImg<T> _base = std::strstr(expression,
"i(")?+*
this:
CImg<T>(), &base = _base?_base:*
this;
10460 _cimg_math_parser mp(base,expression,
"operator+=");
10462 cimg_forXYZC(*
this,x,y,z,c) { *ptrd = (T)(*ptrd + mp.eval(x,y,z,c)); ++ptrd; }
10465 *
this+=
CImg<T>(_width,_height,_depth,_spectrum,expression,
true);
10491 template<
typename t>
10493 const unsigned long siz =
size(), isiz = img.size();
10496 T *ptrd = _data, *
const ptre = _data + siz;
10497 if (siz>isiz)
for (
unsigned long n = siz/isiz; n; --n)
10498 for (
const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs<ptrs_end; ++ptrd) *ptrd = (T)(*ptrd + *(ptrs++));
10499 for (
const t *ptrs = img._data; ptrd<ptre; ++ptrd) *ptrd = (T)(*ptrd + *(ptrs++));
10511 cimg_for(*
this,ptrd,T) ++*ptrd;
10523 const CImg<T> copy(*
this,
false);
10546 template<
typename t>
10565 template<
typename t>
10574 template<
typename t>
10576 cimg_for(*
this,ptrd,T) *ptrd = (T)(*ptrd - value);
10588 const CImg<T> _base = std::strstr(expression,
"i(")?+*
this:
CImg<T>(), &base = _base?_base:*
this;
10589 _cimg_math_parser mp(base,expression,
"operator-=");
10591 cimg_forXYZC(*
this,x,y,z,c) { *ptrd = (T)(*ptrd - mp.eval(x,y,z,c)); ++ptrd; }
10594 *
this-=
CImg<T>(_width,_height,_depth,_spectrum,expression,
true);
10604 template<
typename t>
10606 const unsigned long siz =
size(), isiz = img.size();
10609 T *ptrd = _data, *
const ptre = _data + siz;
10610 if (siz>isiz)
for (
unsigned long n = siz/isiz; n; --n)
10611 for (
const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs<ptrs_end; ++ptrd) *ptrd = (T)(*ptrd - *(ptrs++));
10612 for (
const t *ptrs = img._data; ptrd<ptre; ++ptrd) *ptrd = (T)(*ptrd - *(ptrs++));
10622 cimg_for(*
this,ptrd,T) *ptrd = *ptrd-(T)1;
10631 const CImg<T> copy(*
this,
false);
10651 return CImg<T>(_width,_height,_depth,_spectrum,(T)0)-=*
this;
10659 template<
typename t>
10678 template<
typename t>
10687 template<
typename t>
10689 cimg_for(*
this,ptrd,T) *ptrd = (T)(*ptrd * value);
10701 const CImg<T> _base = std::strstr(expression,
"i(")?+*
this:
CImg<T>(), &base = _base?_base:*
this;
10702 _cimg_math_parser mp(base,expression,
"operator*=");
10704 cimg_forXYZC(*
this,x,y,z,c) { *ptrd = (T)(*ptrd * mp.eval(x,y,z,c)); ++ptrd; }
10707 mul(
CImg<T>(_width,_height,_depth,_spectrum,expression,
true));
10728 template<
typename t>
10730 return ((*
this)*img).
move_to(*
this);
10738 template<
typename t>
10757 template<
typename t>
10759 if (_width!=img._height || _depth!=1 || _spectrum!=1)
10761 "operator*(): Invalid multiplication of instance by specified matrix (%u,%u,%u,%u,%p)",
10763 img._width,img._height,img._depth,img._spectrum,img._data);
10765 _cimg_Ttdouble value;
10766 #ifdef cimg_use_openmp
10767 #pragma omp parallel for if (size()>=1000 && img.size()>=1000) private(value)
10768 cimg_forXY(res,i,j) { value = 0; cimg_forX(*
this,k) value+=(*this)(k,j)*img(i,k); res(i,j) = (_cimg_Tt)value; }
10770 _cimg_Tt *ptrd = res._data;
10771 cimg_forXY(res,i,j) { value = 0; cimg_forX(*
this,k) value+=(*this)(k,j)*img(i,k); *(ptrd++) = (_cimg_Tt)value; }
10780 template<
typename t>
10782 cimg_for(*
this,ptrd,T) *ptrd = (T)(*ptrd / value);
10794 const CImg<T> _base = std::strstr(expression,
"i(")?+*
this:
CImg<T>(), &base = _base?_base:*
this;
10795 _cimg_math_parser mp(base,expression,
"operator/=");
10797 cimg_forXYZC(*
this,x,y,z,c) { *ptrd = (T)(*ptrd / mp.eval(x,y,z,c)); ++ptrd; }
10800 div(
CImg<T>(_width,_height,_depth,_spectrum,expression,
true));
10815 template<
typename t>
10817 return (*
this*img.get_invert()).
move_to(*
this);
10825 template<
typename t>
10844 template<
typename t>
10846 return (*
this)*img.get_invert();
10853 template<
typename t>
10855 cimg_for(*
this,ptrd,T) *ptrd = (T)
cimg::mod(*ptrd,(T)value);
10867 const CImg<T> _base = std::strstr(expression,
"i(")?+*
this:
CImg<T>(), &base = _base?_base:*
this;
10868 _cimg_math_parser mp(base,expression,
"operator%=");
10870 cimg_forXYZC(*
this,x,y,z,c) { *ptrd = (T)
cimg::mod(*ptrd,(T)mp.eval(x,y,z,c)); ++ptrd; }
10873 *
this%=
CImg<T>(_width,_height,_depth,_spectrum,expression,
true);
10883 template<
typename t>
10885 const unsigned long siz =
size(), isiz = img.size();
10888 T *ptrd = _data, *
const ptre = _data + siz;
10889 if (siz>isiz)
for (
unsigned long n = siz/isiz; n; --n)
10890 for (
const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs<ptrs_end; ++ptrd) *ptrd =
cimg::mod(*ptrd,(T)*(ptrs++));
10891 for (
const t *ptrs = img._data; ptrd<ptre; ++ptrd) *ptrd =
cimg::mod(*ptrd,(T)*(ptrs++));
10901 template<
typename t>
10920 template<
typename t>
10929 template<
typename t>
10931 cimg_for(*
this,ptrd,T) *ptrd = (T)((
unsigned long)*ptrd & (
unsigned long)value);
10943 const CImg<T> _base = std::strstr(expression,
"i(")?+*
this:
CImg<T>(), &base = _base?_base:*
this;
10944 _cimg_math_parser mp(base,expression,
"operator&=");
10946 cimg_forXYZC(*
this,x,y,z,c) { *ptrd = (T)((
unsigned long)*ptrd & (
unsigned long)mp.eval(x,y,z,c)); ++ptrd; }
10949 *
this&=
CImg<T>(_width,_height,_depth,_spectrum,expression,
true);
10959 template<
typename t>
10961 const unsigned long siz =
size(), isiz = img.size();
10964 T *ptrd = _data, *
const ptre = _data + siz;
10965 if (siz>isiz)
for (
unsigned long n = siz/isiz; n; --n)
10966 for (
const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs<ptrs_end; ++ptrd) *ptrd = (T)((
unsigned long)*ptrd & (
unsigned long)*(ptrs++));
10967 for (
const t *ptrs = img._data; ptrd<ptre; ++ptrd) *ptrd = (T)((
unsigned long)*ptrd & (
unsigned long)*(ptrs++));
10977 template<
typename t>
10979 return (+*
this)&=value;
10988 return (+*
this)&=expression;
10996 template<
typename t>
10998 return (+*
this)&=img;
11005 template<
typename t>
11007 cimg_for(*
this,ptrd,T) *ptrd = (T)((
unsigned long)*ptrd | (
unsigned long)value);
11019 const CImg<T> _base = std::strstr(expression,
"i(")?+*
this:
CImg<T>(), &base = _base?_base:*
this;
11020 _cimg_math_parser mp(base,expression,
"operator|=");
11022 cimg_forXYZC(*
this,x,y,z,c) { *ptrd = (T)((
unsigned long)*ptrd | (
unsigned long)mp.eval(x,y,z,c)); ++ptrd; }
11025 *
this|=
CImg<T>(_width,_height,_depth,_spectrum,expression,
true);
11035 template<
typename t>
11037 const unsigned long siz =
size(), isiz = img.size();
11040 T *ptrd = _data, *
const ptre = _data + siz;
11041 if (siz>isiz)
for (
unsigned long n = siz/isiz; n; --n)
11042 for (
const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs<ptrs_end; ++ptrd) *ptrd = (T)((
unsigned long)*ptrd | (
unsigned long)*(ptrs++));
11043 for (
const t *ptrs = img._data; ptrd<ptre; ++ptrd) *ptrd = (T)((
unsigned long)*ptrd | (
unsigned long)*(ptrs++));
11053 template<
typename t>
11055 return (+*
this)|=value;
11064 return (+*
this)|=expression;
11072 template<
typename t>
11074 return (+*
this)|=img;
11083 template<
typename t>
11085 cimg_for(*
this,ptrd,T) *ptrd = (T)((
unsigned long)*ptrd ^ (
unsigned long)value);
11099 const CImg<T> _base = std::strstr(expression,
"i(")?+*
this:
CImg<T>(), &base = _base?_base:*
this;
11100 _cimg_math_parser mp(base,expression,
"operator^=");
11102 cimg_forXYZC(*
this,x,y,z,c) { *ptrd = (T)((
unsigned long)*ptrd ^ (
unsigned long)mp.eval(x,y,z,c)); ++ptrd; }
11105 *
this^=
CImg<T>(_width,_height,_depth,_spectrum,expression,
true);
11117 template<
typename t>
11119 const unsigned long siz =
size(), isiz = img.size();
11122 T *ptrd = _data, *
const ptre = _data + siz;
11123 if (siz>isiz)
for (
unsigned long n = siz/isiz; n; --n)
11124 for (
const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs<ptrs_end; ++ptrd) *ptrd = (T)((
unsigned long)*ptrd ^ (
unsigned long)*(ptrs++));
11125 for (
const t *ptrs = img._data; ptrd<ptre; ++ptrd) *ptrd = (T)((
unsigned long)*ptrd ^ (
unsigned long)*(ptrs++));
11135 template<
typename t>
11137 return (+*
this)^=value;
11146 return (+*
this)^=expression;
11154 template<
typename t>
11156 return (+*
this)^=img;
11163 template<
typename t>
11165 cimg_for(*
this,ptrd,T) *ptrd = (T)(((
long)*ptrd) << (int)value);
11177 const CImg<T> _base = std::strstr(expression,
"i(")?+*
this:
CImg<T>(), &base = _base?_base:*
this;
11178 _cimg_math_parser mp(base,expression,
"operator<<=");
11180 cimg_forXYZC(*
this,x,y,z,c) { *ptrd = (T)((
long)*ptrd << (int)mp.eval(x,y,z,c)); ++ptrd; }
11183 *this<<=CImg<T>(_width,_height,_depth,_spectrum,expression,
true);
11193 template<
typename t>
11195 const unsigned long siz =
size(), isiz = img.size();
11198 T *ptrd = _data, *
const ptre = _data + siz;
11199 if (siz>isiz)
for (
unsigned long n = siz/isiz; n; --n)
11200 for (
const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs<ptrs_end; ++ptrd) *ptrd = (T)((
long)*ptrd << (int)*(ptrs++));
11201 for (
const t *ptrs = img._data; ptrd<ptre; ++ptrd) *ptrd = (T)((
long)*ptrd << (int)*(ptrs++));
11211 template<
typename t>
11213 return (+*
this)<<=value;
11222 return (+*
this)<<=expression;
11230 template<
typename t>
11232 return (+*
this)<<=img;
11239 template<
typename t>
11241 cimg_for(*
this,ptrd,T) *ptrd = (T)(((
long)*ptrd) >> (int)value);
11253 const CImg<T> _base = std::strstr(expression,
"i(")?+*
this:
CImg<T>(), &base = _base?_base:*
this;
11254 _cimg_math_parser mp(base,expression,
"operator<<=");
11256 cimg_forXYZC(*
this,x,y,z,c) { *ptrd = (T)((
long)*ptrd >> (int)mp.eval(x,y,z,c)); ++ptrd; }
11259 *
this>>=
CImg<T>(_width,_height,_depth,_spectrum,expression,
true);
11269 template<
typename t>
11271 const unsigned long siz =
size(), isiz = img.size();
11274 T *ptrd = _data, *
const ptre = _data + siz;
11275 if (siz>isiz)
for (
unsigned long n = siz/isiz; n; --n)
11276 for (
const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs<ptrs_end; ++ptrd) *ptrd = (T)((
long)*ptrd >> (int)*(ptrs++));
11277 for (
const t *ptrs = img._data; ptrd<ptre; ++ptrd) *ptrd = (T)((
long)*ptrd >> (int)*(ptrs++));
11287 template<
typename t>
11289 return (+*
this)>>=value;
11298 return (+*
this)>>=expression;
11306 template<
typename t>
11308 return (+*
this)>>=img;
11316 CImg<T> res(_width,_height,_depth,_spectrum);
11317 const T *ptrs = _data;
11318 cimg_for(res,ptrd,T) {
const unsigned long value = (
unsigned long)*(ptrs++); *ptrd = (T)~value; }
11327 template<
typename t>
11330 typedef _cimg_Tt Tt;
11331 bool is_equal =
true;
11332 for (T *ptrd = _data +
size(); is_equal && ptrd>_data; is_equal = ((Tt)*(--ptrd)==(Tt)value)) {}
11342 if (
is_empty())
return !*expression;
11345 bool is_equal =
true;
11347 const CImg<T> _base = std::strstr(expression,
"i(")?+*
this:
CImg<T>(), &base = _base?_base:*
this;
11348 _cimg_math_parser mp(base,expression,
"operator<<=");
11349 const T *ptrs = _data;
11350 cimg_forXYZC(*
this,x,y,z,c) {
if (!is_equal)
break; is_equal = ((double)*(ptrs++)==mp.eval(x,y,z,c)); }
11353 is_equal = (*
this==
CImg<T>(_width,_height,_depth,_spectrum,expression,
true));
11375 template<
typename t>
11377 typedef _cimg_Tt Tt;
11378 const unsigned long siz =
size();
11379 bool is_equal =
true;
11380 if (siz!=img.size())
return false;
11381 t *ptrs = img._data + siz;
11382 for (T *ptrd = _data + siz; is_equal && ptrd>_data; is_equal = ((Tt)*(--ptrd)==(Tt)*(--ptrs))) {}
11391 template<
typename t>
11393 return !((*this)==value);
11402 return !((*this)==expression);
11412 template<
typename t>
11414 return !((*this)==img);
11446 template<
typename t>
11461 template<
typename t>
11516 return (
int)_width;
11530 return (
int)_height;
11546 return (
int)_depth;
11564 return (
int)_spectrum;
11583 return (
unsigned long)_width*_height*_depth*_spectrum;
11617 #if cimg_verbosity>=3
11618 T *
data(
const unsigned int x,
const unsigned int y=0,
const unsigned int z=0,
const unsigned int c=0) {
11619 const unsigned long off = (
unsigned long)
offset(x,y,z,c);
11622 "data(): Invalid pointer request, at coordinates (%u,%u,%u,%u) [offset=%u].",
11627 return _data + off;
11631 const T*
data(
const unsigned int x,
const unsigned int y=0,
const unsigned int z=0,
const unsigned int c=0)
const {
11632 return const_cast<CImg<T>*
>(
this)->
data(x,y,z,c);
11635 T*
data(
const unsigned int x,
const unsigned int y=0,
const unsigned int z=0,
const unsigned int c=0) {
11636 return _data + x + y*(
unsigned long)_width + z*(
unsigned long)_width*_height + c*(
unsigned long)_width*_height*_depth;
11639 const T*
data(
const unsigned int x,
const unsigned int y=0,
const unsigned int z=0,
const unsigned int c=0)
const {
11640 return _data + x + y*_width + z*(
unsigned long)_width*_height + c*(
unsigned long)_width*_height*_depth;
11660 long offset(
const int x,
const int y=0,
const int z=0,
const int c=0)
const {
11661 return x + y*(long)_width + z*(
long)_width*_height + c*(long)_width*_height*_depth;
11696 return _data +
size();
11701 return _data +
size();
11727 return *(_data +
size() - 1);
11732 return *(_data +
size() - 1);
11754 return (offset<0 || offset>=(
int)
size())?out_value:(*this)[
offset];
11774 "at(): Empty instance.",
11776 return _at(offset);
11779 T& _at(
const int offset) {
11780 const unsigned int siz = (
unsigned int)
size();
11781 return (*
this)[offset<0?0:(unsigned int)offset>=siz?siz-1:
offset];
11785 T
at(
const int offset)
const {
11788 "at(): Empty instance.",
11790 return _at(offset);
11793 T _at(
const int offset)
const {
11794 const unsigned int siz = (
unsigned int)
size();
11795 return (*
this)[offset<0?0:(unsigned int)offset>=siz?siz-1:
offset];
11814 T&
atX(
const int x,
const int y,
const int z,
const int c,
const T out_value) {
11819 T
atX(
const int x,
const int y,
const int z,
const int c,
const T out_value)
const {
11820 return (x<0 || x>=
width())?out_value:(*this)(x,y,z,c);
11840 T&
atX(
const int x,
const int y=0,
const int z=0,
const int c=0) {
11843 "atX(): Empty instance.",
11845 return _atX(x,y,z,c);
11848 T& _atX(
const int x,
const int y=0,
const int z=0,
const int c=0) {
11849 return (*
this)(x<0?0:(x>=
width()?
width()-1:x),y,z,c);
11853 T
atX(
const int x,
const int y=0,
const int z=0,
const int c=0)
const {
11856 "atX(): Empty instance.",
11858 return _atX(x,y,z,c);
11861 T _atX(
const int x,
const int y=0,
const int z=0,
const int c=0)
const {
11862 return (*
this)(x<0?0:(x>=
width()?
width()-1:x),y,z,c);
11869 T&
atXY(
const int x,
const int y,
const int z,
const int c,
const T out_value) {
11874 T
atXY(
const int x,
const int y,
const int z,
const int c,
const T out_value)
const {
11875 return (x<0 || y<0 || x>=
width() || y>=
height())?out_value:(*this)(x,y,z,c);
11884 T&
atXY(
const int x,
const int y,
const int z=0,
const int c=0) {
11887 "atXY(): Empty instance.",
11889 return _atXY(x,y,z,c);
11892 T& _atXY(
const int x,
const int y,
const int z=0,
const int c=0) {
11897 T
atXY(
const int x,
const int y,
const int z=0,
const int c=0)
const {
11900 "atXY(): Empty instance.",
11902 return _atXY(x,y,z,c);
11905 T _atXY(
const int x,
const int y,
const int z=0,
const int c=0)
const {
11913 T&
atXYZ(
const int x,
const int y,
const int z,
const int c,
const T out_value) {
11919 T
atXYZ(
const int x,
const int y,
const int z,
const int c,
const T out_value)
const {
11920 return (x<0 || y<0 || z<0 || x>=
width() || y>=
height() || z>=
depth())?out_value:(*this)(x,y,z,c);
11929 T&
atXYZ(
const int x,
const int y,
const int z,
const int c=0) {
11932 "atXYZ(): Empty instance.",
11934 return _atXYZ(x,y,z,c);
11937 T& _atXYZ(
const int x,
const int y,
const int z,
const int c=0) {
11943 T
atXYZ(
const int x,
const int y,
const int z,
const int c=0)
const {
11946 "atXYZ(): Empty instance.",
11948 return _atXYZ(x,y,z,c);
11951 T _atXYZ(
const int x,
const int y,
const int z,
const int c=0)
const {
11960 T&
atXYZC(
const int x,
const int y,
const int z,
const int c,
const T out_value) {
11966 T
atXYZC(
const int x,
const int y,
const int z,
const int c,
const T out_value)
const {
11967 return (x<0 || y<0 || z<0 || c<0 || x>=
width() || y>=
height() || z>=
depth() || c>=
spectrum())?out_value:(*this)(x,y,z,c);
11976 T&
atXYZC(
const int x,
const int y,
const int z,
const int c) {
11979 "atXYZC(): Empty instance.",
11981 return _atXYZC(x,y,z,c);
11984 T& _atXYZC(
const int x,
const int y,
const int z,
const int c) {
11990 T
atXYZC(
const int x,
const int y,
const int z,
const int c)
const {
11993 "atXYZC(): Empty instance.",
11995 return _atXYZC(x,y,z,c);
11998 T _atXYZC(
const int x,
const int y,
const int z,
const int c)
const {
12019 Tfloat
linear_atX(
const float fx,
const int y,
const int z,
const int c,
const T out_value)
const {
12021 x = (int)fx - (fx>=0?0:1), nx = x + 1;
12025 Ic = (Tfloat)
atX(x,y,z,c,out_value), In = (Tfloat)
atXY(nx,y,z,c,out_value);
12026 return Ic + dx*(In-Ic);
12044 Tfloat
linear_atX(
const float fx,
const int y=0,
const int z=0,
const int c=0)
const {
12047 "linear_atX(): Empty instance.",
12050 return _linear_atX(fx,y,z,c);
12053 Tfloat _linear_atX(
const float fx,
const int y=0,
const int z=0,
const int c=0)
const {
12055 nfx = fx<0?0:(fx>_width-1?_width-1:fx);
12057 x = (
unsigned int)nfx;
12063 Ic = (Tfloat)(*
this)(x,y,z,c), In = (Tfloat)(*this)(nx,y,z,c);
12064 return Ic + dx*(In-Ic);
12072 Tfloat
linear_atXY(
const float fx,
const float fy,
const int z,
const int c,
const T out_value)
const {
12074 x = (int)fx - (fx>=0?0:1), nx = x + 1,
12075 y = (int)fy - (fy>=0?0:1), ny = y + 1;
12080 Icc = (Tfloat)
atXY(x,y,z,c,out_value), Inc = (Tfloat)
atXY(nx,y,z,c,out_value),
12081 Icn = (Tfloat)
atXY(x,ny,z,c,out_value), Inn = (Tfloat)
atXY(nx,ny,z,c,out_value);
12082 return Icc + dx*(Inc-Icc + dy*(Icc+Inn-Icn-Inc)) + dy*(Icn-Icc);
12092 Tfloat
linear_atXY(
const float fx,
const float fy,
const int z=0,
const int c=0)
const {
12095 "linear_atXY(): Empty instance.",
12098 return _linear_atXY(fx,fy,z,c);
12101 Tfloat _linear_atXY(
const float fx,
const float fy,
const int z=0,
const int c=0)
const {
12103 nfx = fx<0?0:(fx>_width-1?_width-1:fx),
12104 nfy = fy<0?0:(fy>_height-1?_height-1:fy);
12106 x = (
unsigned int)nfx,
12107 y = (
unsigned int)nfy;
12115 Icc = (Tfloat)(*
this)(x,y,z,c), Inc = (Tfloat)(*this)(nx,y,z,c),
12116 Icn = (Tfloat)(*this)(x,ny,z,c), Inn = (Tfloat)(*this)(nx,ny,z,c);
12117 return Icc + dx*(Inc-Icc + dy*(Icc+Inn-Icn-Inc)) + dy*(Icn-Icc);
12125 Tfloat
linear_atXYZ(
const float fx,
const float fy,
const float fz,
const int c,
const T out_value)
const {
12127 x = (int)fx - (fx>=0?0:1), nx = x + 1,
12128 y = (int)fy - (fy>=0?0:1), ny = y + 1,
12129 z = (int)fz - (fz>=0?0:1), nz = z + 1;
12135 Iccc = (Tfloat)
atXYZ(x,y,z,c,out_value), Incc = (Tfloat)
atXYZ(nx,y,z,c,out_value),
12136 Icnc = (Tfloat)
atXYZ(x,ny,z,c,out_value), Innc = (Tfloat)
atXYZ(nx,ny,z,c,out_value),
12137 Iccn = (Tfloat)
atXYZ(x,y,nz,c,out_value), Incn = (Tfloat)
atXYZ(nx,y,nz,c,out_value),
12138 Icnn = (Tfloat)
atXYZ(x,ny,nz,c,out_value), Innn = (Tfloat)
atXYZ(nx,ny,nz,c,out_value);
12141 dy*(Iccc+Innc-Icnc-Incc +
12142 dz*(Iccn+Innn+Icnc+Incc-Icnn-Incn-Iccc-Innc)) +
12143 dz*(Iccc+Incn-Iccn-Incc)) +
12145 dz*(Iccc+Icnn-Iccn-Icnc)) +
12156 Tfloat
linear_atXYZ(
const float fx,
const float fy=0,
const float fz=0,
const int c=0)
const {
12159 "linear_atXYZ(): Empty instance.",
12162 return _linear_atXYZ(fx,fy,fz,c);
12165 Tfloat _linear_atXYZ(
const float fx,
const float fy=0,
const float fz=0,
const int c=0)
const {
12167 nfx = fx<0?0:(fx>_width-1?_width-1:fx),
12168 nfy = fy<0?0:(fy>_height-1?_height-1:fy),
12169 nfz = fz<0?0:(fz>_depth-1?_depth-1:fz);
12171 x = (
unsigned int)nfx,
12172 y = (
unsigned int)nfy,
12173 z = (
unsigned int)nfz;
12183 Iccc = (Tfloat)(*
this)(x,y,z,c), Incc = (Tfloat)(*this)(nx,y,z,c),
12184 Icnc = (Tfloat)(*this)(x,ny,z,c), Innc = (Tfloat)(*this)(nx,ny,z,c),
12185 Iccn = (Tfloat)(*this)(x,y,nz,c), Incn = (Tfloat)(*this)(nx,y,nz,c),
12186 Icnn = (Tfloat)(*this)(x,ny,nz,c), Innn = (Tfloat)(*this)(nx,ny,nz,c);
12189 dy*(Iccc+Innc-Icnc-Incc +
12190 dz*(Iccn+Innn+Icnc+Incc-Icnn-Incn-Iccc-Innc)) +
12191 dz*(Iccc+Incn-Iccn-Incc)) +
12193 dz*(Iccc+Icnn-Iccn-Icnc)) +
12202 Tfloat
linear_atXYZC(
const float fx,
const float fy,
const float fz,
const float fc,
const T out_value)
const {
12204 x = (int)fx - (fx>=0?0:1), nx = x + 1,
12205 y = (int)fy - (fy>=0?0:1), ny = y + 1,
12206 z = (int)fz - (fz>=0?0:1), nz = z + 1,
12207 c = (int)fc - (fc>=0?0:1), nc = c + 1;
12214 Icccc = (Tfloat)
atXYZC(x,y,z,c,out_value), Inccc = (Tfloat)
atXYZC(nx,y,z,c,out_value),
12215 Icncc = (Tfloat)
atXYZC(x,ny,z,c,out_value), Inncc = (Tfloat)
atXYZC(nx,ny,z,c,out_value),
12216 Iccnc = (Tfloat)
atXYZC(x,y,nz,c,out_value), Incnc = (Tfloat)
atXYZC(nx,y,nz,c,out_value),
12217 Icnnc = (Tfloat)
atXYZC(x,ny,nz,c,out_value), Innnc = (Tfloat)
atXYZC(nx,ny,nz,c,out_value),
12218 Icccn = (Tfloat)
atXYZC(x,y,z,nc,out_value), Inccn = (Tfloat)
atXYZC(nx,y,z,nc,out_value),
12219 Icncn = (Tfloat)
atXYZC(x,ny,z,nc,out_value), Inncn = (Tfloat)
atXYZC(nx,ny,z,nc,out_value),
12220 Iccnn = (Tfloat)
atXYZC(x,y,nz,nc,out_value), Incnn = (Tfloat)
atXYZC(nx,y,nz,nc,out_value),
12221 Icnnn = (Tfloat)
atXYZC(x,ny,nz,nc,out_value), Innnn = (Tfloat)
atXYZC(nx,ny,nz,nc,out_value);
12224 dy*(Icccc+Inncc-Icncc-Inccc +
12225 dz*(Iccnc+Innnc+Icncc+Inccc-Icnnc-Incnc-Icccc-Inncc +
12226 dc*(Iccnn+Innnn+Icncn+Inccn+Icnnc+Incnc+Icccc+Inncc-Icnnn-Incnn-Icccn-Inncn-Iccnc-Innnc-Icncc-Inccc)) +
12227 dc*(Icccn+Inncn+Icncc+Inccc-Icncn-Inccn-Icccc-Inncc)) +
12228 dz*(Icccc+Incnc-Iccnc-Inccc +
12229 dc*(Icccn+Incnn+Iccnc+Inccc-Iccnn-Inccn-Icccc-Incnc)) +
12230 dc*(Icccc+Inccn-Inccc-Icccn)) +
12232 dz*(Icccc+Icnnc-Iccnc-Icncc +
12233 dc*(Icccn+Icnnn+Iccnc+Icncc-Iccnn-Icncn-Icccc-Icnnc)) +
12234 dc*(Icccc+Icncn-Icncc-Icccn)) +
12236 dc*(Icccc+Iccnn-Iccnc-Icccn)) +
12247 Tfloat
linear_atXYZC(
const float fx,
const float fy=0,
const float fz=0,
const float fc=0)
const {
12250 "linear_atXYZC(): Empty instance.",
12253 return _linear_atXYZC(fx,fy,fz,fc);
12256 Tfloat _linear_atXYZC(
const float fx,
const float fy=0,
const float fz=0,
const float fc=0)
const {
12258 nfx = fx<0?0:(fx>_width-1?_width-1:fx),
12259 nfy = fy<0?0:(fy>_height-1?_height-1:fy),
12260 nfz = fz<0?0:(fz>_depth-1?_depth-1:fz),
12261 nfc = fc<0?0:(fc>_spectrum-1?_spectrum-1:fc);
12263 x = (
unsigned int)nfx,
12264 y = (
unsigned int)nfy,
12265 z = (
unsigned int)nfz,
12266 c = (
unsigned int)nfc;
12278 Icccc = (Tfloat)(*
this)(x,y,z,c), Inccc = (Tfloat)(*this)(nx,y,z,c),
12279 Icncc = (Tfloat)(*this)(x,ny,z,c), Inncc = (Tfloat)(*this)(nx,ny,z,c),
12280 Iccnc = (Tfloat)(*this)(x,y,nz,c), Incnc = (Tfloat)(*this)(nx,y,nz,c),
12281 Icnnc = (Tfloat)(*this)(x,ny,nz,c), Innnc = (Tfloat)(*this)(nx,ny,nz,c),
12282 Icccn = (Tfloat)(*this)(x,y,z,nc), Inccn = (Tfloat)(*this)(nx,y,z,nc),
12283 Icncn = (Tfloat)(*this)(x,ny,z,nc), Inncn = (Tfloat)(*this)(nx,ny,z,nc),
12284 Iccnn = (Tfloat)(*this)(x,y,nz,nc), Incnn = (Tfloat)(*this)(nx,y,nz,nc),
12285 Icnnn = (Tfloat)(*this)(x,ny,nz,nc), Innnn = (Tfloat)(*this)(nx,ny,nz,nc);
12288 dy*(Icccc+Inncc-Icncc-Inccc +
12289 dz*(Iccnc+Innnc+Icncc+Inccc-Icnnc-Incnc-Icccc-Inncc +
12290 dc*(Iccnn+Innnn+Icncn+Inccn+Icnnc+Incnc+Icccc+Inncc-Icnnn-Incnn-Icccn-Inncn-Iccnc-Innnc-Icncc-Inccc)) +
12291 dc*(Icccn+Inncn+Icncc+Inccc-Icncn-Inccn-Icccc-Inncc)) +
12292 dz*(Icccc+Incnc-Iccnc-Inccc +
12293 dc*(Icccn+Incnn+Iccnc+Inccc-Iccnn-Inccn-Icccc-Incnc)) +
12294 dc*(Icccc+Inccn-Inccc-Icccn)) +
12296 dz*(Icccc+Icnnc-Iccnc-Icncc +
12297 dc*(Icccn+Icnnn+Iccnc+Icncc-Iccnn-Icncn-Icccc-Icnnc)) +
12298 dc*(Icccc+Icncn-Icncc-Icccn)) +
12300 dc*(Icccc+Iccnn-Iccnc-Icccn)) +
12320 Tfloat
cubic_atX(
const float fx,
const int y,
const int z,
const int c,
const T out_value)
const {
12322 x = (int)fx - (fx>=0?0:1), px = x - 1, nx = x + 1, ax = x + 2;
12326 Ip = (Tfloat)
atX(px,y,z,c,out_value), Ic = (Tfloat)
atX(x,y,z,c,out_value),
12327 In = (Tfloat)
atX(nx,y,z,c,out_value), Ia = (Tfloat)
atX(ax,y,z,c,out_value);
12328 return Ic + 0.5f*(dx*(-Ip+In) + dx*dx*(2*Ip-5*Ic+4*In-Ia) + dx*dx*dx*(-Ip+3*Ic-3*In+Ia));
12335 Tfloat
cubic_atX(
const float fx,
const int y,
const int z,
const int c,
const T out_value,
12336 const Tfloat min_value,
const Tfloat max_value)
const {
12337 const Tfloat val =
cubic_atX(fx,y,z,c,out_value);
12338 return val<min_value?min_value:val>max_value?max_value:val;
12355 Tfloat
cubic_atX(
const float fx,
const int y=0,
const int z=0,
const int c=0)
const {
12358 "cubic_atX(): Empty instance.",
12360 return _cubic_atX(fx,y,z,c);
12363 Tfloat _cubic_atX(
const float fx,
const int y=0,
const int z=0,
const int c=0)
const {
12365 nfx = fx<0?0:(fx>_width-1?_width-1:fx);
12371 px = x-1<0?0:x-1, nx = dx>0?x+1:x, ax = x+2>=
width()?
width()-1:x+2;
12373 Ip = (Tfloat)(*
this)(px,y,z,c), Ic = (Tfloat)(*this)(x,y,z,c),
12374 In = (Tfloat)(*this)(nx,y,z,c), Ia = (Tfloat)(*this)(ax,y,z,c);
12375 return Ic + 0.5f*(dx*(-Ip+In) + dx*dx*(2*Ip-5*Ic+4*In-Ia) + dx*dx*dx*(-Ip+3*Ic-3*In+Ia));
12382 Tfloat
cubic_atX(
const float fx,
const int y,
const int z,
const int c,
12383 const Tfloat min_value,
const Tfloat max_value)
const {
12384 const Tfloat val =
cubic_atX(fx,y,z,c);
12385 return val<min_value?min_value:val>max_value?max_value:val;
12388 Tfloat _cubic_atX(
const float fx,
const int y,
const int z,
const int c,
12389 const Tfloat min_value,
const Tfloat max_value)
const {
12390 const Tfloat val = _cubic_atX(fx,y,z,c);
12391 return val<min_value?min_value:val>max_value?max_value:val;
12399 Tfloat
cubic_atXY(
const float fx,
const float fy,
const int z,
const int c,
const T out_value)
const {
12401 x = (int)fx - (fx>=0?0:1), px = x - 1, nx = x + 1, ax = x + 2,
12402 y = (int)fy - (fy>=0?0:1), py = y - 1, ny = y + 1, ay = y + 2;
12403 const float dx = fx - x, dy = fy - y;
12405 Ipp = (Tfloat)
atXY(px,py,z,c,out_value), Icp = (Tfloat)
atXY(x,py,z,c,out_value), Inp = (Tfloat)
atXY(nx,py,z,c,out_value), Iap = (Tfloat)
atXY(ax,py,z,c,out_value),
12406 Ip = Icp + 0.5f*(dx*(-Ipp+Inp) + dx*dx*(2*Ipp-5*Icp+4*Inp-Iap) + dx*dx*dx*(-Ipp+3*Icp-3*Inp+Iap)),
12407 Ipc = (Tfloat)
atXY(px,y,z,c,out_value), Icc = (Tfloat)
atXY(x, y,z,c,out_value), Inc = (Tfloat)
atXY(nx,y,z,c,out_value), Iac = (Tfloat)
atXY(ax,y,z,c,out_value),
12408 Ic = Icc + 0.5f*(dx*(-Ipc+Inc) + dx*dx*(2*Ipc-5*Icc+4*Inc-Iac) + dx*dx*dx*(-Ipc+3*Icc-3*Inc+Iac)),
12409 Ipn = (Tfloat)
atXY(px,ny,z,c,out_value), Icn = (Tfloat)
atXY(x,ny,z,c,out_value), Inn = (Tfloat)
atXY(nx,ny,z,c,out_value), Ian = (Tfloat)
atXY(ax,ny,z,c,out_value),
12410 In = Icn + 0.5f*(dx*(-Ipn+Inn) + dx*dx*(2*Ipn-5*Icn+4*Inn-Ian) + dx*dx*dx*(-Ipn+3*Icn-3*Inn+Ian)),
12411 Ipa = (Tfloat)
atXY(px,ay,z,c,out_value), Ica = (Tfloat)
atXY(x,ay,z,c,out_value), Ina = (Tfloat)
atXY(nx,ay,z,c,out_value), Iaa = (Tfloat)
atXY(ax,ay,z,c,out_value),
12412 Ia = Ica + 0.5f*(dx*(-Ipa+Ina) + dx*dx*(2*Ipa-5*Ica+4*Ina-Iaa) + dx*dx*dx*(-Ipa+3*Ica-3*Ina+Iaa));
12413 return Ic + 0.5f*(dy*(-Ip+In) + dy*dy*(2*Ip-5*Ic+4*In-Ia) + dy*dy*dy*(-Ip+3*Ic-3*In+Ia));
12420 Tfloat
cubic_atXY(
const float fx,
const float fy,
const int z,
const int c,
const T out_value,
12421 const Tfloat min_value,
const Tfloat max_value)
const {
12422 const Tfloat val =
cubic_atXY(fx,fy,z,c,out_value);
12423 return val<min_value?min_value:val>max_value?max_value:val;
12433 Tfloat
cubic_atXY(
const float fx,
const float fy,
const int z=0,
const int c=0)
const {
12436 "cubic_atXY(): Empty instance.",
12438 return _cubic_atXY(fx,fy,z,c);
12441 Tfloat _cubic_atXY(
const float fx,
const float fy,
const int z=0,
const int c=0)
const {
12443 nfx = fx<0?0:(fx>_width-1?_width-1:fx),
12444 nfy = fy<0?0:(fy>_height-1?_height-1:fy);
12445 const int x = (int)nfx, y = (
int)nfy;
12446 const float dx = nfx - x, dy = nfy - y;
12448 px = x-1<0?0:x-1, nx = dx>0?x+1:x, ax = x+2>=
width()?
width()-1:x+2,
12449 py = y-1<0?0:y-1, ny = dy>0?y+1:y, ay = y+2>=
height()?
height()-1:y+2;
12451 Ipp = (Tfloat)(*
this)(px,py,z,c), Icp = (Tfloat)(*this)(x,py,z,c), Inp = (Tfloat)(*this)(nx,py,z,c), Iap = (Tfloat)(*this)(ax,py,z,c),
12452 Ip = Icp + 0.5f*(dx*(-Ipp+Inp) + dx*dx*(2*Ipp-5*Icp+4*Inp-Iap) + dx*dx*dx*(-Ipp+3*Icp-3*Inp+Iap)),
12453 Ipc = (Tfloat)(*this)(px,y,z,c), Icc = (Tfloat)(*this)(x, y,z,c), Inc = (Tfloat)(*this)(nx,y,z,c), Iac = (Tfloat)(*this)(ax,y,z,c),
12454 Ic = Icc + 0.5f*(dx*(-Ipc+Inc) + dx*dx*(2*Ipc-5*Icc+4*Inc-Iac) + dx*dx*dx*(-Ipc+3*Icc-3*Inc+Iac)),
12455 Ipn = (Tfloat)(*this)(px,ny,z,c), Icn = (Tfloat)(*this)(x,ny,z,c), Inn = (Tfloat)(*this)(nx,ny,z,c), Ian = (Tfloat)(*this)(ax,ny,z,c),
12456 In = Icn + 0.5f*(dx*(-Ipn+Inn) + dx*dx*(2*Ipn-5*Icn+4*Inn-Ian) + dx*dx*dx*(-Ipn+3*Icn-3*Inn+Ian)),
12457 Ipa = (Tfloat)(*this)(px,ay,z,c), Ica = (Tfloat)(*this)(x,ay,z,c), Ina = (Tfloat)(*this)(nx,ay,z,c), Iaa = (Tfloat)(*this)(ax,ay,z,c),
12458 Ia = Ica + 0.5f*(dx*(-Ipa+Ina) + dx*dx*(2*Ipa-5*Ica+4*Ina-Iaa) + dx*dx*dx*(-Ipa+3*Ica-3*Ina+Iaa));
12459 return Ic + 0.5f*(dy*(-Ip+In) + dy*dy*(2*Ip-5*Ic+4*In-Ia) + dy*dy*dy*(-Ip+3*Ic-3*In+Ia));
12466 Tfloat
cubic_atXY(
const float fx,
const float fy,
const int z,
const int c,
12467 const Tfloat min_value,
const Tfloat max_value)
const {
12469 return val<min_value?min_value:val>max_value?max_value:val;
12472 Tfloat _cubic_atXY(
const float fx,
const float fy,
const int z,
const int c,
12473 const Tfloat min_value,
const Tfloat max_value)
const {
12474 const Tfloat val = _cubic_atXY(fx,fy,z,c);
12475 return val<min_value?min_value:val>max_value?max_value:val;
12483 Tfloat
cubic_atXYZ(
const float fx,
const float fy,
const float fz,
const int c,
const T out_value)
const {
12485 x = (int)fx - (fx>=0?0:1), px = x - 1, nx = x + 1, ax = x + 2,
12486 y = (int)fy - (fy>=0?0:1), py = y - 1, ny = y + 1, ay = y + 2,
12487 z = (int)fz - (fz>=0?0:1), pz = z - 1, nz = z + 1, az = z + 2;
12488 const float dx = fx - x, dy = fy - y, dz = fz - z;
12490 Ippp = (Tfloat)
atXYZ(px,py,pz,c,out_value), Icpp = (Tfloat)
atXYZ(x,py,pz,c,out_value),
12491 Inpp = (Tfloat)
atXYZ(nx,py,pz,c,out_value), Iapp = (Tfloat)
atXYZ(ax,py,pz,c,out_value),
12492 Ipp = Icpp + 0.5f*(dx*(-Ippp+Inpp) + dx*dx*(2*Ippp-5*Icpp+4*Inpp-Iapp) + dx*dx*dx*(-Ippp+3*Icpp-3*Inpp+Iapp)),
12493 Ipcp = (Tfloat)
atXYZ(px,y,pz,c,out_value), Iccp = (Tfloat)
atXYZ(x, y,pz,c,out_value),
12494 Incp = (Tfloat)
atXYZ(nx,y,pz,c,out_value), Iacp = (Tfloat)
atXYZ(ax,y,pz,c,out_value),
12495 Icp = Iccp + 0.5f*(dx*(-Ipcp+Incp) + dx*dx*(2*Ipcp-5*Iccp+4*Incp-Iacp) + dx*dx*dx*(-Ipcp+3*Iccp-3*Incp+Iacp)),
12496 Ipnp = (Tfloat)
atXYZ(px,ny,pz,c,out_value), Icnp = (Tfloat)
atXYZ(x,ny,pz,c,out_value),
12497 Innp = (Tfloat)
atXYZ(nx,ny,pz,c,out_value), Ianp = (Tfloat)
atXYZ(ax,ny,pz,c,out_value),
12498 Inp = Icnp + 0.5f*(dx*(-Ipnp+Innp) + dx*dx*(2*Ipnp-5*Icnp+4*Innp-Ianp) + dx*dx*dx*(-Ipnp+3*Icnp-3*Innp+Ianp)),
12499 Ipap = (Tfloat)
atXYZ(px,ay,pz,c,out_value), Icap = (Tfloat)
atXYZ(x,ay,pz,c,out_value),
12500 Inap = (Tfloat)
atXYZ(nx,ay,pz,c,out_value), Iaap = (Tfloat)
atXYZ(ax,ay,pz,c,out_value),
12501 Iap = Icap + 0.5f*(dx*(-Ipap+Inap) + dx*dx*(2*Ipap-5*Icap+4*Inap-Iaap) + dx*dx*dx*(-Ipap+3*Icap-3*Inap+Iaap)),
12502 Ip = Icp + 0.5f*(dy*(-Ipp+Inp) + dy*dy*(2*Ipp-5*Icp+4*Inp-Iap) + dy*dy*dy*(-Ipp+3*Icp-3*Inp+Iap)),
12503 Ippc = (Tfloat)
atXYZ(px,py,z,c,out_value), Icpc = (Tfloat)
atXYZ(x,py,z,c,out_value),
12504 Inpc = (Tfloat)
atXYZ(nx,py,z,c,out_value), Iapc = (Tfloat)
atXYZ(ax,py,z,c,out_value),
12505 Ipc = Icpc + 0.5f*(dx*(-Ippc+Inpc) + dx*dx*(2*Ippc-5*Icpc+4*Inpc-Iapc) + dx*dx*dx*(-Ippc+3*Icpc-3*Inpc+Iapc)),
12506 Ipcc = (Tfloat)
atXYZ(px,y,z,c,out_value), Iccc = (Tfloat)
atXYZ(x, y,z,c,out_value),
12507 Incc = (Tfloat)
atXYZ(nx,y,z,c,out_value), Iacc = (Tfloat)
atXYZ(ax,y,z,c,out_value),
12508 Icc = Iccc + 0.5f*(dx*(-Ipcc+Incc) + dx*dx*(2*Ipcc-5*Iccc+4*Incc-Iacc) + dx*dx*dx*(-Ipcc+3*Iccc-3*Incc+Iacc)),
12509 Ipnc = (Tfloat)
atXYZ(px,ny,z,c,out_value), Icnc = (Tfloat)
atXYZ(x,ny,z,c,out_value),
12510 Innc = (Tfloat)
atXYZ(nx,ny,z,c,out_value), Ianc = (Tfloat)
atXYZ(ax,ny,z,c,out_value),
12511 Inc = Icnc + 0.5f*(dx*(-Ipnc+Innc) + dx*dx*(2*Ipnc-5*Icnc+4*Innc-Ianc) + dx*dx*dx*(-Ipnc+3*Icnc-3*Innc+Ianc)),
12512 Ipac = (Tfloat)
atXYZ(px,ay,z,c,out_value), Icac = (Tfloat)
atXYZ(x,ay,z,c,out_value),
12513 Inac = (Tfloat)
atXYZ(nx,ay,z,c,out_value), Iaac = (Tfloat)
atXYZ(ax,ay,z,c,out_value),
12514 Iac = Icac + 0.5f*(dx*(-Ipac+Inac) + dx*dx*(2*Ipac-5*Icac+4*Inac-Iaac) + dx*dx*dx*(-Ipac+3*Icac-3*Inac+Iaac)),
12515 Ic = Icc + 0.5f*(dy*(-Ipc+Inc) + dy*dy*(2*Ipc-5*Icc+4*Inc-Iac) + dy*dy*dy*(-Ipc+3*Icc-3*Inc+Iac)),
12516 Ippn = (Tfloat)
atXYZ(px,py,nz,c,out_value), Icpn = (Tfloat)
atXYZ(x,py,nz,c,out_value),
12517 Inpn = (Tfloat)
atXYZ(nx,py,nz,c,out_value), Iapn = (Tfloat)
atXYZ(ax,py,nz,c,out_value),
12518 Ipn = Icpn + 0.5f*(dx*(-Ippn+Inpn) + dx*dx*(2*Ippn-5*Icpn+4*Inpn-Iapn) + dx*dx*dx*(-Ippn+3*Icpn-3*Inpn+Iapn)),
12519 Ipcn = (Tfloat)
atXYZ(px,y,nz,c,out_value), Iccn = (Tfloat)
atXYZ(x, y,nz,c,out_value),
12520 Incn = (Tfloat)
atXYZ(nx,y,nz,c,out_value), Iacn = (Tfloat)
atXYZ(ax,y,nz,c,out_value),
12521 Icn = Iccn + 0.5f*(dx*(-Ipcn+Incn) + dx*dx*(2*Ipcn-5*Iccn+4*Incn-Iacn) + dx*dx*dx*(-Ipcn+3*Iccn-3*Incn+Iacn)),
12522 Ipnn = (Tfloat)
atXYZ(px,ny,nz,c,out_value), Icnn = (Tfloat)
atXYZ(x,ny,nz,c,out_value),
12523 Innn = (Tfloat)
atXYZ(nx,ny,nz,c,out_value), Iann = (Tfloat)
atXYZ(ax,ny,nz,c,out_value),
12524 Inn = Icnn + 0.5f*(dx*(-Ipnn+Innn) + dx*dx*(2*Ipnn-5*Icnn+4*Innn-Iann) + dx*dx*dx*(-Ipnn+3*Icnn-3*Innn+Iann)),
12525 Ipan = (Tfloat)
atXYZ(px,ay,nz,c,out_value), Ican = (Tfloat)
atXYZ(x,ay,nz,c,out_value),
12526 Inan = (Tfloat)
atXYZ(nx,ay,nz,c,out_value), Iaan = (Tfloat)
atXYZ(ax,ay,nz,c,out_value),
12527 Ian = Ican + 0.5f*(dx*(-Ipan+Inan) + dx*dx*(2*Ipan-5*Ican+4*Inan-Iaan) + dx*dx*dx*(-Ipan+3*Ican-3*Inan+Iaan)),
12528 In = Icn + 0.5f*(dy*(-Ipn+Inn) + dy*dy*(2*Ipn-5*Icn+4*Inn-Ian) + dy*dy*dy*(-Ipn+3*Icn-3*Inn+Ian)),
12529 Ippa = (Tfloat)
atXYZ(px,py,az,c,out_value), Icpa = (Tfloat)
atXYZ(x,py,az,c,out_value),
12530 Inpa = (Tfloat)
atXYZ(nx,py,az,c,out_value), Iapa = (Tfloat)
atXYZ(ax,py,az,c,out_value),
12531 Ipa = Icpa + 0.5f*(dx*(-Ippa+Inpa) + dx*dx*(2*Ippa-5*Icpa+4*Inpa-Iapa) + dx*dx*dx*(-Ippa+3*Icpa-3*Inpa+Iapa)),
12532 Ipca = (Tfloat)
atXYZ(px,y,az,c,out_value), Icca = (Tfloat)
atXYZ(x, y,az,c,out_value),
12533 Inca = (Tfloat)
atXYZ(nx,y,az,c,out_value), Iaca = (Tfloat)
atXYZ(ax,y,az,c,out_value),
12534 Ica = Icca + 0.5f*(dx*(-Ipca+Inca) + dx*dx*(2*Ipca-5*Icca+4*Inca-Iaca) + dx*dx*dx*(-Ipca+3*Icca-3*Inca+Iaca)),
12535 Ipna = (Tfloat)
atXYZ(px,ny,az,c,out_value), Icna = (Tfloat)
atXYZ(x,ny,az,c,out_value),
12536 Inna = (Tfloat)
atXYZ(nx,ny,az,c,out_value), Iana = (Tfloat)
atXYZ(ax,ny,az,c,out_value),
12537 Ina = Icna + 0.5f*(dx*(-Ipna+Inna) + dx*dx*(2*Ipna-5*Icna+4*Inna-Iana) + dx*dx*dx*(-Ipna+3*Icna-3*Inna+Iana)),
12538 Ipaa = (Tfloat)
atXYZ(px,ay,az,c,out_value), Icaa = (Tfloat)
atXYZ(x,ay,az,c,out_value),
12539 Inaa = (Tfloat)
atXYZ(nx,ay,az,c,out_value), Iaaa = (Tfloat)
atXYZ(ax,ay,az,c,out_value),
12540 Iaa = Icaa + 0.5f*(dx*(-Ipaa+Inaa) + dx*dx*(2*Ipaa-5*Icaa+4*Inaa-Iaaa) + dx*dx*dx*(-Ipaa+3*Icaa-3*Inaa+Iaaa)),
12541 Ia = Ica + 0.5f*(dy*(-Ipa+Ina) + dy*dy*(2*Ipa-5*Ica+4*Ina-Iaa) + dy*dy*dy*(-Ipa+3*Ica-3*Ina+Iaa));
12542 return Ic + 0.5f*(dz*(-Ip+In) + dz*dz*(2*Ip-5*Ic+4*In-Ia) + dz*dz*dz*(-Ip+3*Ic-3*In+Ia));
12549 Tfloat
cubic_atXYZ(
const float fx,
const float fy,
const float fz,
const int c,
const T out_value,
12550 const Tfloat min_value,
const Tfloat max_value)
const {
12551 const Tfloat val =
cubic_atXYZ(fx,fy,fz,c,out_value);
12552 return val<min_value?min_value:val>max_value?max_value:val;
12562 Tfloat
cubic_atXYZ(
const float fx,
const float fy,
const float fz,
const int c=0)
const {
12565 "cubic_atXYZ(): Empty instance.",
12567 return _cubic_atXYZ(fx,fy,fz,c);
12570 Tfloat _cubic_atXYZ(
const float fx,
const float fy,
const float fz,
const int c=0)
const {
12572 nfx = fx<0?0:(fx>_width-1?_width-1:fx),
12573 nfy = fy<0?0:(fy>_height-1?_height-1:fy),
12574 nfz = fz<0?0:(fz>_depth-1?_depth-1:fz);
12575 const int x = (int)nfx, y = (
int)nfy, z = (int)nfz;
12576 const float dx = nfx - x, dy = nfy - y, dz = nfz - z;
12578 px = x-1<0?0:x-1, nx = dx>0?x+1:x, ax = x+2>=
width()?
width()-1:x+2,
12579 py = y-1<0?0:y-1, ny = dy>0?y+1:y, ay = y+2>=
height()?
height()-1:y+2,
12580 pz = z-1<0?0:z-1, nz = dz>0?z+1:z, az = z+2>=
depth()?
depth()-1:z+2;
12582 Ippp = (Tfloat)(*
this)(px,py,pz,c), Icpp = (Tfloat)(*this)(x,py,pz,c),
12583 Inpp = (Tfloat)(*this)(nx,py,pz,c), Iapp = (Tfloat)(*this)(ax,py,pz,c),
12584 Ipp = Icpp + 0.5f*(dx*(-Ippp+Inpp) + dx*dx*(2*Ippp-5*Icpp+4*Inpp-Iapp) + dx*dx*dx*(-Ippp+3*Icpp-3*Inpp+Iapp)),
12585 Ipcp = (Tfloat)(*this)(px,y,pz,c), Iccp = (Tfloat)(*this)(x, y,pz,c),
12586 Incp = (Tfloat)(*this)(nx,y,pz,c), Iacp = (Tfloat)(*this)(ax,y,pz,c),
12587 Icp = Iccp + 0.5f*(dx*(-Ipcp+Incp) + dx*dx*(2*Ipcp-5*Iccp+4*Incp-Iacp) + dx*dx*dx*(-Ipcp+3*Iccp-3*Incp+Iacp)),
12588 Ipnp = (Tfloat)(*this)(px,ny,pz,c), Icnp = (Tfloat)(*this)(x,ny,pz,c),
12589 Innp = (Tfloat)(*this)(nx,ny,pz,c), Ianp = (Tfloat)(*this)(ax,ny,pz,c),
12590 Inp = Icnp + 0.5f*(dx*(-Ipnp+Innp) + dx*dx*(2*Ipnp-5*Icnp+4*Innp-Ianp) + dx*dx*dx*(-Ipnp+3*Icnp-3*Innp+Ianp)),
12591 Ipap = (Tfloat)(*this)(px,ay,pz,c), Icap = (Tfloat)(*this)(x,ay,pz,c),
12592 Inap = (Tfloat)(*this)(nx,ay,pz,c), Iaap = (Tfloat)(*this)(ax,ay,pz,c),
12593 Iap = Icap + 0.5f*(dx*(-Ipap+Inap) + dx*dx*(2*Ipap-5*Icap+4*Inap-Iaap) + dx*dx*dx*(-Ipap+3*Icap-3*Inap+Iaap)),
12594 Ip = Icp + 0.5f*(dy*(-Ipp+Inp) + dy*dy*(2*Ipp-5*Icp+4*Inp-Iap) + dy*dy*dy*(-Ipp+3*Icp-3*Inp+Iap)),
12595 Ippc = (Tfloat)(*this)(px,py,z,c), Icpc = (Tfloat)(*this)(x,py,z,c),
12596 Inpc = (Tfloat)(*this)(nx,py,z,c), Iapc = (Tfloat)(*this)(ax,py,z,c),
12597 Ipc = Icpc + 0.5f*(dx*(-Ippc+Inpc) + dx*dx*(2*Ippc-5*Icpc+4*Inpc-Iapc) + dx*dx*dx*(-Ippc+3*Icpc-3*Inpc+Iapc)),
12598 Ipcc = (Tfloat)(*this)(px,y,z,c), Iccc = (Tfloat)(*this)(x, y,z,c),
12599 Incc = (Tfloat)(*this)(nx,y,z,c), Iacc = (Tfloat)(*this)(ax,y,z,c),
12600 Icc = Iccc + 0.5f*(dx*(-Ipcc+Incc) + dx*dx*(2*Ipcc-5*Iccc+4*Incc-Iacc) + dx*dx*dx*(-Ipcc+3*Iccc-3*Incc+Iacc)),
12601 Ipnc = (Tfloat)(*this)(px,ny,z,c), Icnc = (Tfloat)(*this)(x,ny,z,c),
12602 Innc = (Tfloat)(*this)(nx,ny,z,c), Ianc = (Tfloat)(*this)(ax,ny,z,c),
12603 Inc = Icnc + 0.5f*(dx*(-Ipnc+Innc) + dx*dx*(2*Ipnc-5*Icnc+4*Innc-Ianc) + dx*dx*dx*(-Ipnc+3*Icnc-3*Innc+Ianc)),
12604 Ipac = (Tfloat)(*this)(px,ay,z,c), Icac = (Tfloat)(*this)(x,ay,z,c),
12605 Inac = (Tfloat)(*this)(nx,ay,z,c), Iaac = (Tfloat)(*this)(ax,ay,z,c),
12606 Iac = Icac + 0.5f*(dx*(-Ipac+Inac) + dx*dx*(2*Ipac-5*Icac+4*Inac-Iaac) + dx*dx*dx*(-Ipac+3*Icac-3*Inac+Iaac)),
12607 Ic = Icc + 0.5f*(dy*(-Ipc+Inc) + dy*dy*(2*Ipc-5*Icc+4*Inc-Iac) + dy*dy*dy*(-Ipc+3*Icc-3*Inc+Iac)),
12608 Ippn = (Tfloat)(*this)(px,py,nz,c), Icpn = (Tfloat)(*this)(x,py,nz,c),
12609 Inpn = (Tfloat)(*this)(nx,py,nz,c), Iapn = (Tfloat)(*this)(ax,py,nz,c),
12610 Ipn = Icpn + 0.5f*(dx*(-Ippn+Inpn) + dx*dx*(2*Ippn-5*Icpn+4*Inpn-Iapn) + dx*dx*dx*(-Ippn+3*Icpn-3*Inpn+Iapn)),
12611 Ipcn = (Tfloat)(*this)(px,y,nz,c), Iccn = (Tfloat)(*this)(x, y,nz,c),
12612 Incn = (Tfloat)(*this)(nx,y,nz,c), Iacn = (Tfloat)(*this)(ax,y,nz,c),
12613 Icn = Iccn + 0.5f*(dx*(-Ipcn+Incn) + dx*dx*(2*Ipcn-5*Iccn+4*Incn-Iacn) + dx*dx*dx*(-Ipcn+3*Iccn-3*Incn+Iacn)),
12614 Ipnn = (Tfloat)(*this)(px,ny,nz,c), Icnn = (Tfloat)(*this)(x,ny,nz,c),
12615 Innn = (Tfloat)(*this)(nx,ny,nz,c), Iann = (Tfloat)(*this)(ax,ny,nz,c),
12616 Inn = Icnn + 0.5f*(dx*(-Ipnn+Innn) + dx*dx*(2*Ipnn-5*Icnn+4*Innn-Iann) + dx*dx*dx*(-Ipnn+3*Icnn-3*Innn+Iann)),
12617 Ipan = (Tfloat)(*this)(px,ay,nz,c), Ican = (Tfloat)(*this)(x,ay,nz,c),
12618 Inan = (Tfloat)(*this)(nx,ay,nz,c), Iaan = (Tfloat)(*this)(ax,ay,nz,c),
12619 Ian = Ican + 0.5f*(dx*(-Ipan+Inan) + dx*dx*(2*Ipan-5*Ican+4*Inan-Iaan) + dx*dx*dx*(-Ipan+3*Ican-3*Inan+Iaan)),
12620 In = Icn + 0.5f*(dy*(-Ipn+Inn) + dy*dy*(2*Ipn-5*Icn+4*Inn-Ian) + dy*dy*dy*(-Ipn+3*Icn-3*Inn+Ian)),
12621 Ippa = (Tfloat)(*this)(px,py,az,c), Icpa = (Tfloat)(*this)(x,py,az,c),
12622 Inpa = (Tfloat)(*this)(nx,py,az,c), Iapa = (Tfloat)(*this)(ax,py,az,c),
12623 Ipa = Icpa + 0.5f*(dx*(-Ippa+Inpa) + dx*dx*(2*Ippa-5*Icpa+4*Inpa-Iapa) + dx*dx*dx*(-Ippa+3*Icpa-3*Inpa+Iapa)),
12624 Ipca = (Tfloat)(*this)(px,y,az,c), Icca = (Tfloat)(*this)(x, y,az,c),
12625 Inca = (Tfloat)(*this)(nx,y,az,c), Iaca = (Tfloat)(*this)(ax,y,az,c),
12626 Ica = Icca + 0.5f*(dx*(-Ipca+Inca) + dx*dx*(2*Ipca-5*Icca+4*Inca-Iaca) + dx*dx*dx*(-Ipca+3*Icca-3*Inca+Iaca)),
12627 Ipna = (Tfloat)(*this)(px,ny,az,c), Icna = (Tfloat)(*this)(x,ny,az,c),
12628 Inna = (Tfloat)(*this)(nx,ny,az,c), Iana = (Tfloat)(*this)(ax,ny,az,c),
12629 Ina = Icna + 0.5f*(dx*(-Ipna+Inna) + dx*dx*(2*Ipna-5*Icna+4*Inna-Iana) + dx*dx*dx*(-Ipna+3*Icna-3*Inna+Iana)),
12630 Ipaa = (Tfloat)(*this)(px,ay,az,c), Icaa = (Tfloat)(*this)(x,ay,az,c),
12631 Inaa = (Tfloat)(*this)(nx,ay,az,c), Iaaa = (Tfloat)(*this)(ax,ay,az,c),
12632 Iaa = Icaa + 0.5f*(dx*(-Ipaa+Inaa) + dx*dx*(2*Ipaa-5*Icaa+4*Inaa-Iaaa) + dx*dx*dx*(-Ipaa+3*Icaa-3*Inaa+Iaaa)),
12633 Ia = Ica + 0.5f*(dy*(-Ipa+Ina) + dy*dy*(2*Ipa-5*Ica+4*Ina-Iaa) + dy*dy*dy*(-Ipa+3*Ica-3*Ina+Iaa));
12634 return Ic + 0.5f*(dz*(-Ip+In) + dz*dz*(2*Ip-5*Ic+4*In-Ia) + dz*dz*dz*(-Ip+3*Ic-3*In+Ia));
12641 Tfloat
cubic_atXYZ(
const float fx,
const float fy,
const float fz,
const int c,
12642 const Tfloat min_value,
const Tfloat max_value)
const {
12644 return val<min_value?min_value:val>max_value?max_value:val;
12647 Tfloat _cubic_atXYZ(
const float fx,
const float fy,
const float fz,
const int c,
12648 const Tfloat min_value,
const Tfloat max_value)
const {
12649 const Tfloat val = _cubic_atXYZ(fx,fy,fz,c);
12650 return val<min_value?min_value:val>max_value?max_value:val;
12668 const bool is_added=
false) {
12670 x = (int)fx - (fx>=0?0:1), nx = x + 1,
12671 y = (int)fy - (fy>=0?0:1), ny = y + 1;
12676 if (y>=0 && y<
height()) {
12677 if (x>=0 && x<
width()) {
12678 const float w1 = (1-dx)*(1-dy), w2 = is_added?1:(1-w1);
12679 (*this)(x,y,z,c) = (T)(w1*value + w2*(*this)(x,y,z,c));
12681 if (nx>=0 && nx<
width()) {
12682 const float w1 = dx*(1-dy), w2 = is_added?1:(1-w1);
12683 (*this)(nx,y,z,c) = (T)(w1*value + w2*(*this)(nx,y,z,c));
12686 if (ny>=0 && ny<
height()) {
12687 if (x>=0 && x<
width()) {
12688 const float w1 = (1-dx)*dy, w2 = is_added?1:(1-w1);
12689 (*this)(x,ny,z,c) = (T)(w1*value + w2*(*this)(x,ny,z,c));
12691 if (nx>=0 && nx<
width()) {
12692 const float w1 = dx*dy, w2 = is_added?1:(1-w1);
12693 (*this)(nx,ny,z,c) = (T)(w1*value + w2*(*this)(nx,ny,z,c));
12706 const bool is_added=
false) {
12708 x = (int)fx - (fx>=0?0:1), nx = x + 1,
12709 y = (int)fy - (fy>=0?0:1), ny = y + 1,
12710 z = (int)fz - (fz>=0?0:1), nz = z + 1;
12716 if (z>=0 && z<
depth()) {
12717 if (y>=0 && y<
height()) {
12718 if (x>=0 && x<
width()) {
12719 const float w1 = (1-dx)*(1-dy)*(1-dz), w2 = is_added?1:(1-w1);
12720 (*this)(x,y,z,c) = (T)(w1*value + w2*(*this)(x,y,z,c));
12722 if (nx>=0 && nx<
width()) {
12723 const float w1 = dx*(1-dy)*(1-dz), w2 = is_added?1:(1-w1);
12724 (*this)(nx,y,z,c) = (T)(w1*value + w2*(*this)(nx,y,z,c));
12727 if (ny>=0 && ny<
height()) {
12728 if (x>=0 && x<
width()) {
12729 const float w1 = (1-dx)*dy*(1-dz), w2 = is_added?1:(1-w1);
12730 (*this)(x,ny,z,c) = (T)(w1*value + w2*(*this)(x,ny,z,c));
12732 if (nx>=0 && nx<
width()) {
12733 const float w1 = dx*dy*(1-dz), w2 = is_added?1:(1-w1);
12734 (*this)(nx,ny,z,c) = (T)(w1*value + w2*(*this)(nx,ny,z,c));
12738 if (nz>=0 && nz<
depth()) {
12739 if (y>=0 && y<
height()) {
12740 if (x>=0 && x<
width()) {
12741 const float w1 = (1-dx)*(1-dy)*dz, w2 = is_added?1:(1-w1);
12742 (*this)(x,y,nz,c) = (T)(w1*value + w2*(*this)(x,y,nz,c));
12744 if (nx>=0 && nx<
width()) {
12745 const float w1 = dx*(1-dy)*dz, w2 = is_added?1:(1-w1);
12746 (*this)(nx,y,nz,c) = (T)(w1*value + w2*(*this)(nx,y,nz,c));
12749 if (ny>=0 && ny<
height()) {
12750 if (x>=0 && x<
width()) {
12751 const float w1 = (1-dx)*dy*dz, w2 = is_added?1:(1-w1);
12752 (*this)(x,ny,nz,c) = (T)(w1*value + w2*(*this)(x,ny,nz,c));
12754 if (nx>=0 && nx<
width()) {
12755 const float w1 = dx*dy*dz, w2 = is_added?1:(1-w1);
12756 (*this)(nx,ny,nz,c) = (T)(w1*value + w2*(*this)(nx,ny,nz,c));
12780 char s_item[256] = { 0 };
12781 const T *ptrs = _data;
12782 unsigned int string_size = 0;
12783 for (
unsigned long off = 0, siz = (
unsigned int)
size(); off<siz && string_size<=max_size; ++off) {
12786 item[printed_size-1] = separator;
12788 if (max_size) string_size+=printed_size;
12792 if (max_size && res._width>max_size) res.
crop(0,max_size);
12822 return !(_data && _width && _height && _depth && _spectrum);
12845 return _width==size_x;
12849 template<
typename t>
12861 return _height==size_y;
12865 template<
typename t>
12877 return _depth==size_z;
12881 template<
typename t>
12888 return _spectrum==size_c;
12892 template<
typename t>
12901 bool is_sameXY(
const unsigned int size_x,
const unsigned int size_y)
const {
12902 return _width==size_x && _height==size_y;
12909 template<
typename t>
12911 return is_sameXY(img._width,img._height);
12919 return is_sameXY(disp._width,disp._height);
12926 bool is_sameXZ(
const unsigned int size_x,
const unsigned int size_z)
const {
12927 return _width==size_x && _depth==size_z;
12934 template<
typename t>
12936 return is_sameXZ(img._width,img._depth);
12943 bool is_sameXC(
const unsigned int size_x,
const unsigned int size_c)
const {
12944 return _width==size_x && _spectrum==size_c;
12951 template<
typename t>
12953 return is_sameXC(img._width,img._spectrum);
12960 bool is_sameYZ(
const unsigned int size_y,
const unsigned int size_z)
const {
12961 return _height==size_y && _depth==size_z;
12968 template<
typename t>
12970 return is_sameYZ(img._height,img._depth);
12977 bool is_sameYC(
const unsigned int size_y,
const unsigned int size_c)
const {
12978 return _height==size_y && _spectrum==size_c;
12985 template<
typename t>
12987 return is_sameYC(img._height,img._spectrum);
12994 bool is_sameZC(
const unsigned int size_z,
const unsigned int size_c)
const {
12995 return _depth==size_z && _spectrum==size_c;
13002 template<
typename t>
13004 return is_sameZC(img._depth,img._spectrum);
13011 bool is_sameXYZ(
const unsigned int size_x,
const unsigned int size_y,
const unsigned int size_z)
const {
13012 return is_sameXY(size_x,size_y) && _depth==size_z;
13019 template<
typename t>
13021 return is_sameXYZ(img._width,img._height,img._depth);
13028 bool is_sameXYC(
const unsigned int size_x,
const unsigned int size_y,
const unsigned int size_c)
const {
13029 return is_sameXY(size_x,size_y) && _spectrum==size_c;
13036 template<
typename t>
13038 return is_sameXYC(img._width,img._height,img._spectrum);
13045 bool is_sameXZC(
const unsigned int size_x,
const unsigned int size_z,
const unsigned int size_c)
const {
13046 return is_sameXZ(size_x,size_z) && _spectrum==size_c;
13053 template<
typename t>
13055 return is_sameXZC(img._width,img._depth,img._spectrum);
13062 bool is_sameYZC(
const unsigned int size_y,
const unsigned int size_z,
const unsigned int size_c)
const {
13063 return is_sameYZ(size_y,size_z) && _spectrum==size_c;
13070 template<
typename t>
13072 return is_sameYZC(img._height,img._depth,img._spectrum);
13079 bool is_sameXYZC(
const unsigned int size_x,
const unsigned int size_y,
const unsigned int size_z,
const unsigned int size_c)
const {
13080 return is_sameXYZ(size_x,size_y,size_z) && _spectrum==size_c;
13087 template<
typename t>
13089 return is_sameXYZC(img._width,img._height,img._depth,img._spectrum);
13107 bool containsXYZC(
const int x,
const int y=0,
const int z=0,
const int c=0)
const {
13108 return !
is_empty() && x>=0 && x<width() && y>=0 && y<height() && z>=0 && z<depth() && c>=0 && c<
spectrum();
13131 template<
typename t>
13132 bool contains(
const T& pixel, t& x, t& y, t& z, t& c)
const {
13133 const unsigned long wh = (
unsigned long)_width*_height, whd = wh*_depth, siz = whd*_spectrum;
13134 const T *
const ppixel = &pixel;
13135 if (
is_empty() || ppixel<_data || ppixel>=_data+siz)
return false;
13136 unsigned long off = (
unsigned long)(ppixel - _data);
13137 const unsigned long nc = off/whd;
13139 const unsigned long nz = off/wh;
13141 const unsigned long ny = off/_width, nx = off%_width;
13142 x = (t)nx; y = (t)ny; z = (t)nz; c = (t)nc;
13150 template<
typename t>
13152 const unsigned long wh = (
unsigned long)_width*_height, whd = wh*_depth, siz = whd*_spectrum;
13153 const T *
const ppixel = &pixel;
13154 if (
is_empty() || ppixel<_data || ppixel>=_data+siz)
return false;
13155 unsigned long off = ((
unsigned long)(ppixel - _data))%whd;
13156 const unsigned long nz = off/wh;
13158 const unsigned long ny = off/_width, nx = off%_width;
13159 x = (t)nx; y = (t)ny; z = (t)nz;
13167 template<
typename t>
13169 const unsigned long wh = (
unsigned long)_width*_height, siz = wh*_depth*_spectrum;
13170 const T *
const ppixel = &pixel;
13171 if (
is_empty() || ppixel<_data || ppixel>=_data+siz)
return false;
13172 unsigned long off = ((
unsigned int)(ppixel - _data))%wh;
13173 const unsigned long ny = off/_width, nx = off%_width;
13174 x = (t)nx; y = (t)ny;
13182 template<
typename t>
13184 const T *
const ppixel = &pixel;
13185 if (
is_empty() || ppixel<_data || ppixel>=_data+
size())
return false;
13186 x = (t)(((
unsigned long)(ppixel - _data))%_width);
13195 const T *
const ppixel = &pixel;
13196 return !
is_empty() && ppixel>=_data && ppixel<_data +
size();
13217 template<
typename t>
13219 const unsigned long csiz =
size(), isiz = img.size();
13220 return !((
void*)(_data + csiz)<=(
void*)img._data || (
void*)_data>=(
void*)(img._data + isiz));
13237 template<
typename tp,
typename tc,
typename to>
13240 const to& opacities,
13241 const bool is_full_check=
true,
13242 char *
const error_message=0)
const {
13243 if (error_message) *error_message = 0;
13247 if (primitives || colors || opacities) {
13248 if (error_message) std::sprintf(error_message,
13249 "3d object has no vertices but %u primitives, %u colors and %lu opacities",
13250 primitives._width,colors._width,(
unsigned long)opacities.size());
13257 if (_height!=3 || _depth>1 || _spectrum>1) {
13258 if (error_message) std::sprintf(error_message,
13259 "3d object (%u,%u) has invalid vertices dimensions (%u,%u,%u,%u)",
13260 _width,primitives._width,_width,_height,_depth,_spectrum);
13263 if (colors._width>primitives._width+1) {
13264 if (error_message) std::sprintf(error_message,
13265 "3d object (%u,%u) defines %u colors",
13266 _width,primitives._width,colors._width);
13269 if (opacities.size()>primitives._width) {
13270 if (error_message) std::sprintf(error_message,
13271 "3d object (%u,%u) defines %lu opacities",
13272 _width,primitives._width,(
unsigned long)opacities.size());
13275 if (!is_full_check)
return true;
13278 cimglist_for(primitives,l) {
13279 const CImg<tp>& primitive = primitives[l];
13280 const unsigned long psiz = primitive.size();
13283 const unsigned int i0 = (
unsigned int)primitive(0);
13285 if (error_message) std::sprintf(error_message,
13286 "3d object (%u,%u) refers to invalid vertex indice %u in point primitive %u",
13287 _width,primitives._width,i0,l);
13293 i0 = (
unsigned int)primitive(0),
13294 i1 = (
unsigned int)primitive(1);
13295 if (i0>=_width || i1>=_width) {
13296 if (error_message) std::sprintf(error_message,
13297 "3d object (%u,%u) refers to invalid vertex indices (%u,%u) in sphere primitive %u",
13298 _width,primitives._width,i0,i1,l);
13305 i0 = (
unsigned int)primitive(0),
13306 i1 = (
unsigned int)primitive(1);
13307 if (i0>=_width || i1>=_width) {
13308 if (error_message) std::sprintf(error_message,
13309 "3d object (%u,%u) refers to invalid vertex indices (%u,%u) in segment primitive %u",
13310 _width,primitives._width,i0,i1,l);
13317 i0 = (
unsigned int)primitive(0),
13318 i1 = (
unsigned int)primitive(1),
13319 i2 = (
unsigned int)primitive(2);
13320 if (i0>=_width || i1>=_width || i2>=_width) {
13321 if (error_message) std::sprintf(error_message,
13322 "3d object (%u,%u) refers to invalid vertex indices (%u,%u,%u) in triangle primitive %u",
13323 _width,primitives._width,i0,i1,i2,l);
13330 i0 = (
unsigned int)primitive(0),
13331 i1 = (
unsigned int)primitive(1),
13332 i2 = (
unsigned int)primitive(2),
13333 i3 = (
unsigned int)primitive(3);
13334 if (i0>=_width || i1>=_width || i2>=_width || i3>=_width) {
13335 if (error_message) std::sprintf(error_message,
13336 "3d object (%u,%u) refers to invalid vertex indices (%u,%u,%u,%u) in quadrangle primitive %u",
13337 _width,primitives._width,i0,i1,i2,i3,l);
13342 if (error_message) std::sprintf(error_message,
13343 "3d object has invalid primitive %u of size %u",
13344 l,(
unsigned int)psiz);
13350 cimglist_for(colors,c) {
13351 const CImg<tc>& color = colors[c];
13353 if (error_message) std::sprintf(error_message,
13354 "3d object has empty color for primitive %u",
13361 if (colors._width>primitives._width) {
13363 if (!light || light._depth>1) {
13364 if (error_message) std::sprintf(error_message,
13365 "3d object has invalid light texture (%u,%u,%u,%u)",
13366 light._width,light._height,light._depth,light._spectrum);
13384 bool is_CImg3d(
const bool is_full_check=
true,
char *
const error_message=0)
const {
13385 if (error_message) *error_message = 0;
13388 if (_width!=1 || _height<8 || _depth!=1 || _spectrum!=1) {
13389 if (error_message) std::sprintf(error_message,
13390 "CImg3d has invalid dimensions (%u,%u,%u,%u)",
13391 _width,_height,_depth,_spectrum);
13394 const T *ptrs = _data, *
const ptre =
end();
13395 if (!_is_CImg3d(*(ptrs++),
'C') || !_is_CImg3d(*(ptrs++),
'I') || !_is_CImg3d(*(ptrs++),
'm') ||
13396 !_is_CImg3d(*(ptrs++),
'g') || !_is_CImg3d(*(ptrs++),
'3') || !_is_CImg3d(*(ptrs++),
'd')) {
13397 if (error_message) std::sprintf(error_message,
13398 "CImg3d header not found");
13402 nb_points = cimg::float2uint((
float)*(ptrs++)),
13403 nb_primitives = cimg::float2uint((
float)*(ptrs++));
13407 if (nb_primitives) {
13408 if (error_message) std::sprintf(error_message,
13409 "CImg3d has no vertices but %u primitives",
13414 if (error_message) std::sprintf(error_message,
13415 "CImg3d (%u,%u) is empty but contains %u byte%s more than expected",
13416 nb_points,nb_primitives,(
unsigned int)(ptre-ptrs),(ptre-ptrs)>1?
"s":
"");
13423 if (error_message) std::sprintf(error_message,
13424 "CImg3d (%u,%u) has incomplete vertex data",
13425 nb_points,nb_primitives);
13428 if (!is_full_check)
return true;
13432 if (error_message) std::sprintf(error_message,
13433 "CImg3d (%u,%u) has no primitive data",
13434 nb_points,nb_primitives);
13437 for (
unsigned int p = 0; p<nb_primitives; ++p) {
13438 const unsigned int nb_inds = (
unsigned int)*(ptrs++);
13441 const unsigned int i0 = cimg::float2uint((
float)*(ptrs++));
13442 if (i0>=nb_points) {
13443 if (error_message) std::sprintf(error_message,
13444 "CImg3d (%u,%u) refers to invalid vertex indice %u in point primitive %u",
13445 nb_points,nb_primitives,i0,p);
13451 i0 = cimg::float2uint((
float)*(ptrs++)),
13452 i1 = cimg::float2uint((
float)*(ptrs++));
13454 if (i0>=nb_points || i1>=nb_points) {
13455 if (error_message) std::sprintf(error_message,
13456 "CImg3d (%u,%u) refers to invalid vertex indices (%u,%u) in sphere primitive %u",
13457 nb_points,nb_primitives,i0,i1,p);
13461 case 2 :
case 6 : {
13463 i0 = cimg::float2uint((
float)*(ptrs++)),
13464 i1 = cimg::float2uint((
float)*(ptrs++));
13465 if (nb_inds==6) ptrs+=4;
13466 if (i0>=nb_points || i1>=nb_points) {
13467 if (error_message) std::sprintf(error_message,
13468 "CImg3d (%u,%u) refers to invalid vertex indices (%u,%u) in segment primitive %u",
13469 nb_points,nb_primitives,i0,i1,p);
13473 case 3 :
case 9 : {
13475 i0 = cimg::float2uint((
float)*(ptrs++)),
13476 i1 = cimg::float2uint((
float)*(ptrs++)),
13477 i2 = cimg::float2uint((
float)*(ptrs++));
13478 if (nb_inds==9) ptrs+=6;
13479 if (i0>=nb_points || i1>=nb_points || i2>=nb_points) {
13480 if (error_message) std::sprintf(error_message,
13481 "CImg3d (%u,%u) refers to invalid vertex indices (%u,%u,%u) in triangle primitive %u",
13482 nb_points,nb_primitives,i0,i1,i2,p);
13486 case 4 :
case 12 : {
13488 i0 = cimg::float2uint((
float)*(ptrs++)),
13489 i1 = cimg::float2uint((
float)*(ptrs++)),
13490 i2 = cimg::float2uint((
float)*(ptrs++)),
13491 i3 = cimg::float2uint((
float)*(ptrs++));
13492 if (nb_inds==12) ptrs+=8;
13493 if (i0>=nb_points || i1>=nb_points || i2>=nb_points || i3>=nb_points) {
13494 if (error_message) std::sprintf(error_message,
13495 "CImg3d (%u,%u) refers to invalid vertex indices (%u,%u,%u,%u) in quadrangle primitive %u",
13496 nb_points,nb_primitives,i0,i1,i2,i3,p);
13501 if (error_message) std::sprintf(error_message,
13502 "CImg3d (%u,%u) has invalid primitive %u of size %u",
13503 nb_points,nb_primitives,p,nb_inds);
13507 if (error_message) std::sprintf(error_message,
13508 "CImg3d (%u,%u) has incomplete primitive data for primitive %u",
13509 nb_points,nb_primitives,p);
13516 if (error_message) std::sprintf(error_message,
13517 "CImg3d (%u,%u) has no color/texture data",
13518 nb_points,nb_primitives);
13521 for (
unsigned int c = 0; c<nb_primitives; ++c) {
13522 if (*(ptrs++)!=(T)-128) ptrs+=2;
13523 else if ((ptrs+=3)<ptre) {
13524 const unsigned int w = (
unsigned int)*(ptrs-3), h = (
unsigned int)*(ptrs-2), s = (
unsigned int)*(ptrs-1);
13527 if (error_message) std::sprintf(error_message,
13528 "CImg3d (%u,%u) refers to invalid shared sprite/texture indice %u for primitive %u",
13529 nb_points,nb_primitives,w,c);
13532 }
else ptrs+=w*h*s;
13535 if (error_message) std::sprintf(error_message,
13536 "CImg3d (%u,%u) has incomplete color/texture data for primitive %u",
13537 nb_points,nb_primitives,c);
13544 if (error_message) std::sprintf(error_message,
13545 "CImg3d (%u,%u) has no opacity data",
13546 nb_points,nb_primitives);
13549 for (
unsigned int o = 0; o<nb_primitives; ++o) {
13550 if (*(ptrs++)==(T)-128 && (ptrs+=3)<ptre) {
13551 const unsigned int w = (
unsigned int)*(ptrs-3), h = (
unsigned int)*(ptrs-2), s = (
unsigned int)*(ptrs-1);
13554 if (error_message) std::sprintf(error_message,
13555 "CImg3d (%u,%u) refers to invalid shared opacity indice %u for primitive %u",
13556 nb_points,nb_primitives,w,o);
13559 }
else ptrs+=w*h*s;
13562 if (error_message) std::sprintf(error_message,
13563 "CImg3d (%u,%u) has incomplete opacity data for primitive %u",
13564 nb_points,nb_primitives,o);
13571 if (error_message) std::sprintf(error_message,
13572 "CImg3d (%u,%u) contains %u byte%s more than expected",
13573 nb_points,nb_primitives,(
unsigned int)(ptre-ptrs),(ptre-ptrs)>1?
"s":
"");
13579 static bool _is_CImg3d(
const T val,
const char c) {
13580 return val>=(T)c && val<(T)(c+1);
13599 unsigned int mempos, result;
13600 const char *
const calling_function;
13601 #define _cimg_mp_return(x) { *se = saved_char; return x; }
13602 #define _cimg_mp_opcode0(op) _cimg_mp_return(opcode0(op));
13603 #define _cimg_mp_opcode1(op,i1) _cimg_mp_return(opcode1(op,i1));
13604 #define _cimg_mp_opcode2(op,i1,i2) { const unsigned int _i1 = i1, _i2 = i2; _cimg_mp_return(opcode2(op,_i1,_i2)); }
13605 #define _cimg_mp_opcode3(op,i1,i2,i3) { const unsigned int _i1 = i1, _i2 = i2, _i3 = i3; _cimg_mp_return(opcode3(op,_i1,_i2,_i3)); }
13606 #define _cimg_mp_opcode6(op,i1,i2,i3,i4,i5,i6) { const unsigned int _i1 = i1, _i2 = i2, _i3 = i3, _i4 = i4, _i5 = i5, _i6 = i6; \
13607 _cimg_mp_return(opcode6(op,_i1,_i2,_i3,_i4,_i5,_i6)); }
13611 reference(img),calling_function(funcname?funcname:
"cimg_math_parser") {
13612 unsigned int l = 0;
13614 l = (
unsigned int)std::strlen(expression);
13615 expr.
assign(expression,l+1);
13617 char *d = expr._data;
13618 for (
const char *s = expr._data; *s || (
bool)(*d=0); ++s)
if (*s!=
' ') *(d++) = *s;
13619 l = (
unsigned int)(d - expr._data);
13623 "CImg<%s>::%s(): Empty specified expression.",
13628 unsigned int *pd = level._data;
13629 for (
const char *ps = expr._data; *ps && lv>=0; ++ps) *(pd++) = (
unsigned int)(*ps==
'('?lv++:*ps==
')'?--lv:lv);
13632 "CImg<%s>::%s(): Unbalanced parentheses in specified expression '%s'.",
13641 mem[2] = (double)reference._width;
13642 mem[3] = (
double)reference._height;
13643 mem[4] = (double)reference._depth;
13644 mem[5] = (
double)reference._spectrum;
13646 mem[7] = std::exp(1.0);
13648 result = compile(expr._data,expr._data+l);
13652 unsigned int opcode0(
const char op) {
13653 if (mempos>=mem._width) mem.
resize(-200,1,1,1,0);
13654 const unsigned int pos = mempos++;
13659 unsigned int opcode1(
const char op,
const unsigned int arg1) {
13660 if (mempos>=mem._width) mem.
resize(-200,1,1,1,0);
13661 const unsigned int pos = mempos++;
13666 unsigned int opcode2(
const char op,
const unsigned int arg1,
const unsigned int arg2) {
13667 if (mempos>=mem._width) mem.
resize(-200,1,1,1,0);
13668 const unsigned int pos = mempos++;
13673 unsigned int opcode3(
const char op,
const unsigned int arg1,
const unsigned int arg2,
const unsigned int arg3) {
13674 if (mempos>=mem._width) mem.
resize(-200,1,1,1,0);
13675 const unsigned int pos = mempos++;
13680 unsigned int opcode6(
const char op,
const unsigned int arg1,
const unsigned int arg2,
const unsigned int arg3,
13681 const unsigned int arg4,
const unsigned int arg5,
const unsigned int arg6) {
13682 if (mempos>=mem._width) mem.
resize(-200,1,1,1,0);
13683 const unsigned int pos = mempos++;
13689 unsigned int compile(
char *
const ss,
char *
const se) {
13690 if (!ss || se<=ss || !*ss) {
13692 "CImg<%s>::%s(): Missing item in specified expression '%s'.",
13697 *
const se1 = se-1, *
const se2 = se-2, *
const se3 = se-3, *
const se4 = se-4,
13698 *
const ss1 = ss+1, *
const ss2 = ss+2, *
const ss3 = ss+3, *
const ss4 = ss+4,
13699 *
const ss5 = ss+5, *
const ss6 = ss+6, *
const ss7 = ss+7;
13700 const char saved_char = *se; *se = 0;
13701 const unsigned int clevel = level[ss-expr._data], clevel1 = clevel+1;
13702 if (*se1==
';')
return compile(ss,se1);
13705 char end = 0, sep = 0;
double val = 0;
13706 const int nb = std::sscanf(ss,
"%lf%c%c",&val,&sep,&end);
13708 if (val==0) _cimg_mp_return(0);
13709 if (val==1) _cimg_mp_return(1);
13710 if (mempos>=mem._width) mem.
resize(-200,1,1,1,0);
13711 const unsigned int pos = mempos++;
13713 _cimg_mp_return(pos);
13715 if (nb==2 && sep==
'%') {
13716 if (val==0) _cimg_mp_return(0);
13717 if (val==100) _cimg_mp_return(1);
13718 if (mempos>=mem._width) mem.
resize(-200,1,1,1,0);
13719 const unsigned int pos = mempos++;
13720 mem[pos] = val/100;
13721 _cimg_mp_return(pos);
13723 if (ss1==se)
switch (*ss) {
13724 case 'w' : _cimg_mp_return(2);
case 'h' : _cimg_mp_return(3);
case 'd' : _cimg_mp_return(4);
case 's' : _cimg_mp_return(5);
13725 case 'x' : _cimg_mp_return(8);
case 'y' : _cimg_mp_return(9);
case 'z' : _cimg_mp_return(10);
case 'c' : _cimg_mp_return(11);
13726 case 'e' : _cimg_mp_return(7);
13727 case 'u' :
case '?' : _cimg_mp_opcode2(0,0,1);
13728 case 'g' : _cimg_mp_opcode0(1);
13729 case 'i' : _cimg_mp_opcode0(2);
13732 if (*ss==
'p' && *ss1==
'i') _cimg_mp_return(6);
13734 if (*ss1==
'm') _cimg_mp_opcode0(57);
13735 if (*ss1==
'M') _cimg_mp_opcode0(58);
13736 if (*ss1==
'a') _cimg_mp_opcode0(59);
13737 if (*ss1==
'v') _cimg_mp_opcode0(60);
13740 if (*ss==
'x') _cimg_mp_opcode0(61);
13741 if (*ss==
'y') _cimg_mp_opcode0(62);
13742 if (*ss==
'z') _cimg_mp_opcode0(63);
13743 if (*ss==
'c') _cimg_mp_opcode0(64);
13746 if (*ss==
'x') _cimg_mp_opcode0(65);
13747 if (*ss==
'y') _cimg_mp_opcode0(66);
13748 if (*ss==
'z') _cimg_mp_opcode0(67);
13749 if (*ss==
'c') _cimg_mp_opcode0(68);
13753 if (*ss==
'x' && *ss1==
'/' && *ss2==
'w') _cimg_mp_opcode0(3);
13754 if (*ss==
'y' && *ss1==
'/' && *ss2==
'h') _cimg_mp_opcode0(4);
13755 if (*ss==
'z' && *ss1==
'/' && *ss2==
'd') _cimg_mp_opcode0(5);
13756 if (*ss==
'c' && *ss1==
'/' && *ss2==
's') _cimg_mp_opcode0(6);
13760 for (
char *s = se2; s>ss; --s)
if (*s==
';' && level[s-expr._data]==clevel) { compile(ss,s); _cimg_mp_return(compile(s+1,se)); }
13761 for (
char *s = ss1, *ps = ss, *ns = ss2; s<se1; ++s, ++ps, ++ns)
13762 if (*s==
'=' && *ns!=
'=' && *ps!=
'=' && *ps!=
'>' && *ps!=
'<' && *ps!=
'!' && level[s-expr._data]==clevel) {
13763 CImg<charT> variable_name(ss,(
unsigned int)(s-ss+1));
13764 variable_name.
back() = 0;
13765 bool is_valid_name =
true;
13766 if ((*ss>=
'0' && *ss<=
'9') ||
13767 (s==ss+1 && (*ss==
'x' || *ss==
'y' || *ss==
'z' || *ss==
'c' ||
13768 *ss==
'w' || *ss==
'h' || *ss==
'd' || *ss==
's' ||
13769 *ss==
'e' || *ss==
'u' || *ss==
'g' || *ss==
'i')) ||
13770 (s==ss+2 && ((*ss==
'p' && *(ss+1)==
'i') ||
13771 (*ss==
'i' && (*(ss+1)==
'm' || *(ss+1)==
'M' || *(ss+1)==
'a' || *(ss+1)==
'v')) ||
13772 (*ss==
'x' && (*(ss+1)==
'm' || *(ss+1)==
'M')) ||
13773 (*ss==
'y' && (*(ss+1)==
'm' || *(ss+1)==
'M')) ||
13774 (*ss==
'z' && (*(ss+1)==
'm' || *(ss+1)==
'M')) ||
13775 (*ss==
'c' && (*(ss+1)==
'm' || *(ss+1)==
'M'))))) is_valid_name =
false;
13776 for (
const char *ns = ss; ns<s; ++ns)
13777 if ((*ns<'a' || *ns>
'z') && (*ns<'A' || *ns>
'Z') && (*ns<'0' || *ns>
'9') && *ns!=
'_') {
13778 is_valid_name =
false;
break;
13780 if (!is_valid_name) {
13782 if (!std::strcmp(variable_name,
"x") || !std::strcmp(variable_name,
"y") || !std::strcmp(variable_name,
"z") ||
13783 !std::strcmp(variable_name,
"c") || !std::strcmp(variable_name,
"w") || !std::strcmp(variable_name,
"h") ||
13784 !std::strcmp(variable_name,
"d") || !std::strcmp(variable_name,
"s") || !std::strcmp(variable_name,
"e") ||
13785 !std::strcmp(variable_name,
"u") || !std::strcmp(variable_name,
"g") || !std::strcmp(variable_name,
"i") ||
13786 !std::strcmp(variable_name,
"pi") || !std::strcmp(variable_name,
"im") || !std::strcmp(variable_name,
"iM") ||
13787 !std::strcmp(variable_name,
"ia") || !std::strcmp(variable_name,
"iv") ||
13788 !std::strcmp(variable_name,
"xm") || !std::strcmp(variable_name,
"ym") ||
13789 !std::strcmp(variable_name,
"zm") || !std::strcmp(variable_name,
"cm") ||
13790 !std::strcmp(variable_name,
"xM") || !std::strcmp(variable_name,
"yM") ||
13791 !std::strcmp(variable_name,
"zM") || !std::strcmp(variable_name,
"cM"))
13793 "CImg<%s>::%s(): Invalid assignment of reserved variable name '%s' in specified expression '%s'.",
13795 variable_name._data,expr._data);
13798 "CImg<%s>::%s(): Invalid variable name '%s' in specified expression '%s'.",
13800 variable_name._data,expr._data);
13802 for (
unsigned int i = 0; i<mempos; ++i)
13803 if (label[i]._data && !std::strcmp(variable_name,label[i])) {
13806 "CImg<%s>::%s(): Invalid multiple assignments of variable '%s' in specified expression '%s'.",
13808 variable_name._data,expr._data);
13810 const unsigned int src_pos = compile(s+1,se);
13811 if (mempos>=mem.
size()) mem.
resize(-200,1,1,1,0);
13812 const unsigned int dest_pos = mempos++;
13813 variable_name.
move_to(label[dest_pos]);
13815 _cimg_mp_return(dest_pos);
13819 for (
char *s = se3, *ns = se2; s>ss; --s, --ns)
if (*s==
'|' && *ns==
'|' && level[s-expr._data]==clevel) _cimg_mp_opcode2(8,compile(ss,s),compile(s+2,se));
13820 for (
char *s = se3, *ns = se2; s>ss; --s, --ns)
if (*s==
'&' && *ns==
'&' && level[s-expr._data]==clevel) _cimg_mp_opcode2(9,compile(ss,s),compile(s+2,se));
13821 for (
char *s = se2; s>ss; --s)
if (*s==
'|' && level[s-expr._data]==clevel) _cimg_mp_opcode2(10,compile(ss,s),compile(s+1,se));
13822 for (
char *s = se2; s>ss; --s)
if (*s==
'&' && level[s-expr._data]==clevel) _cimg_mp_opcode2(11,compile(ss,s),compile(s+1,se));
13823 for (
char *s = se3, *ns = se2; s>ss; --s, --ns)
if (*s==
'!' && *ns==
'=' && level[s-expr._data]==clevel) _cimg_mp_opcode2(12,compile(ss,s),compile(s+2,se));
13824 for (
char *s = se3, *ns = se2; s>ss; --s, --ns)
if (*s==
'=' && *ns==
'=' && level[s-expr._data]==clevel) _cimg_mp_opcode2(13,compile(ss,s),compile(s+2,se));
13825 for (
char *s = se3, *ns = se2; s>ss; --s, --ns)
if (*s==
'<' && *ns==
'=' && level[s-expr._data]==clevel) _cimg_mp_opcode2(14,compile(ss,s),compile(s+2,se));
13826 for (
char *s = se3, *ns = se2; s>ss; --s, --ns)
if (*s==
'>' && *ns==
'=' && level[s-expr._data]==clevel) _cimg_mp_opcode2(15,compile(ss,s),compile(s+2,se));
13827 for (
char *s = se2, *ns = se1, *ps = se3; s>ss; --s, --ns, --ps)
13828 if (*s==
'<' && *ns!=
'<' && *ps!=
'<' && level[s-expr._data]==clevel) _cimg_mp_opcode2(16,compile(ss,s),compile(s+1,se));
13829 for (
char *s = se2, *ns = se1, *ps = se3; s>ss; --s, --ns, --ps)
13830 if (*s==
'>' && *ns!=
'>' && *ps!=
'>' && level[s-expr._data]==clevel) _cimg_mp_opcode2(17,compile(ss,s),compile(s+1,se));
13831 for (
char *s = se3, *ns = se2; s>ss; --s, --ns)
if (*s==
'<' && *ns==
'<' && level[s-expr._data]==clevel) _cimg_mp_opcode2(18,compile(ss,s),compile(s+2,se));
13832 for (
char *s = se3, *ns = se2; s>ss; --s, --ns)
if (*s==
'>' && *ns==
'>' && level[s-expr._data]==clevel) _cimg_mp_opcode2(19,compile(ss,s),compile(s+2,se));
13833 for (
char *s = se2, *ps = se3; s>ss; --s, --ps)
13834 if (*s==
'+' && *ps!=
'-' && *ps!=
'+' && *ps!=
'*' && *ps!=
'/' && *ps!=
'%' && *ps!=
'&' && *ps!=
'|' && *ps!=
'^' && *ps!=
'!' && *ps!=
'~' &&
13835 (*ps!=
'e' || !(ps>ss && (*(ps-1)==
'.' || (*(ps-1)>=
'0' && *(ps-1)<=
'9')))) && level[s-expr._data]==clevel)
13836 _cimg_mp_opcode2(21,compile(ss,s),compile(s+1,se));
13837 for (
char *s = se2, *ps = se3; s>ss; --s, --ps)
13838 if (*s==
'-' && *ps!=
'-' && *ps!=
'+' && *ps!=
'*' && *ps!=
'/' && *ps!=
'%' && *ps!=
'&' && *ps!=
'|' && *ps!=
'^' && *ps!=
'!' && *ps!=
'~' &&
13839 (*ps!=
'e' || !(ps>ss && (*(ps-1)==
'.' || (*(ps-1)>=
'0' && *(ps-1)<=
'9')))) && level[s-expr._data]==clevel)
13840 _cimg_mp_opcode2(20,compile(ss,s),compile(s+1,se));
13841 for (
char *s = se2; s>ss; --s)
if (*s==
'*' && level[s-expr._data]==clevel) _cimg_mp_opcode2(22,compile(ss,s),compile(s+1,se));
13842 for (
char *s = se2; s>ss; --s)
if (*s==
'/' && level[s-expr._data]==clevel) _cimg_mp_opcode2(23,compile(ss,s),compile(s+1,se));
13843 for (
char *s = se2, *ns = se1; s>ss; --s, --ns)
13844 if (*s==
'%' && *ns!=
'^' && level[s-expr._data]==clevel)
13845 _cimg_mp_opcode2(24,compile(ss,s),compile(s+1,se));
13847 if (*ss==
'+') _cimg_mp_return(compile(ss1,se));
13848 if (*ss==
'-') _cimg_mp_opcode1(26,compile(ss1,se));
13849 if (*ss==
'!') _cimg_mp_opcode1(27,compile(ss1,se));
13850 if (*ss==
'~') _cimg_mp_opcode1(28,compile(ss1,se));
13852 for (
char *s = se2; s>ss; --s)
if (*s==
'^' && level[s-expr._data]==clevel) _cimg_mp_opcode2(25,compile(ss,s),compile(s+1,se));
13856 if (*ss==
'(') _cimg_mp_return(compile(ss1,se1));
13857 if (!std::strncmp(ss,
"sin(",4)) _cimg_mp_opcode1(29,compile(ss4,se1));
13858 if (!std::strncmp(ss,
"cos(",4)) _cimg_mp_opcode1(30,compile(ss4,se1));
13859 if (!std::strncmp(ss,
"tan(",4)) _cimg_mp_opcode1(31,compile(ss4,se1));
13860 if (!std::strncmp(ss,
"asin(",5)) _cimg_mp_opcode1(32,compile(ss5,se1));
13861 if (!std::strncmp(ss,
"acos(",5)) _cimg_mp_opcode1(33,compile(ss5,se1));
13862 if (!std::strncmp(ss,
"atan(",5)) _cimg_mp_opcode1(34,compile(ss5,se1));
13863 if (!std::strncmp(ss,
"sinh(",5)) _cimg_mp_opcode1(35,compile(ss5,se1));
13864 if (!std::strncmp(ss,
"cosh(",5)) _cimg_mp_opcode1(36,compile(ss5,se1));
13865 if (!std::strncmp(ss,
"tanh(",5)) _cimg_mp_opcode1(37,compile(ss5,se1));
13866 if (!std::strncmp(ss,
"log10(",6)) _cimg_mp_opcode1(38,compile(ss6,se1));
13867 if (!std::strncmp(ss,
"log2(",5)) _cimg_mp_opcode1(71,compile(ss5,se1));
13868 if (!std::strncmp(ss,
"log(",4)) _cimg_mp_opcode1(39,compile(ss4,se1));
13869 if (!std::strncmp(ss,
"exp(",4)) _cimg_mp_opcode1(40,compile(ss4,se1));
13870 if (!std::strncmp(ss,
"sqrt(",5)) _cimg_mp_opcode1(41,compile(ss5,se1));
13871 if (!std::strncmp(ss,
"sign(",5)) _cimg_mp_opcode1(42,compile(ss5,se1));
13872 if (!std::strncmp(ss,
"abs(",4)) _cimg_mp_opcode1(43,compile(ss4,se1));
13873 if (!std::strncmp(ss,
"atan2(",6)) {
13874 char *s1 = ss6;
while (s1<se2 && (*s1!=
',' || level[s1-expr._data]!=clevel1)) ++s1;
13875 _cimg_mp_opcode2(44,compile(ss6,s1),compile(s1+1,se1));
13877 if (!std::strncmp(ss,
"if(",3)) {
13878 char *s1 = ss3;
while (s1<se4 && (*s1!=
',' || level[s1-expr._data]!=clevel1)) ++s1;
13879 char *s2 = s1+1;
while (s2<se2 && (*s2!=
',' || level[s2-expr._data]!=clevel1)) ++s2;
13880 _cimg_mp_opcode3(45,compile(ss3,s1),compile(s1+1,s2),compile(s2+1,se1));
13882 if (!std::strncmp(ss,
"round(",6)) {
13883 unsigned int value = 0,
round = 1, direction = 0;
13884 char *s1 = ss6;
while (s1<se2 && (*s1!=
',' || level[s1-expr._data]!=clevel1)) ++s1;
13885 value = compile(ss6,s1==se2?++s1:s1);
13887 char *s2 = s1+1;
while (s2<se2 && (*s2!=
',' || level[s2-expr._data]!=clevel1)) ++s2;
13888 round = compile(s1+1,s2==se2?++s2:s2);
13889 if (s2<se1) direction = compile(s2+1,se1);
13891 _cimg_mp_opcode3(46,value,
round,direction);
13893 if (!std::strncmp(ss,
"?(",2) || !std::strncmp(ss,
"u(",2)) {
13894 if (*ss2==
')') _cimg_mp_opcode2(0,0,1);
13895 char *s1 = ss2;
while (s1<se1 && (*s1!=
',' || level[s1-expr._data]!=clevel1)) ++s1;
13896 if (s1<se1) _cimg_mp_opcode2(0,compile(ss2,s1),compile(s1+1,se1));
13897 _cimg_mp_opcode2(0,0,compile(ss2,s1));
13899 if (!std::strncmp(ss,
"i(",2)) {
13900 if (*ss2==
')') _cimg_mp_return(0);
13901 unsigned int indx = 8, indy = 9, indz = 10, indc = 11, borders = 0, interpolation = 0;
13903 char *s1 = ss2;
while (s1<se2 && (*s1!=
',' || level[s1-expr._data]!=clevel1)) ++s1;
13904 indx = compile(ss2,s1==se2?++s1:s1);
13906 char *s2 = s1+1;
while (s2<se2 && (*s2!=
',' || level[s2-expr._data]!=clevel1)) ++s2;
13907 indy = compile(s1+1,s2==se2?++s2:s2);
13909 char *s3 = s2+1;
while (s3<se2 && (*s3!=
',' || level[s3-expr._data]!=clevel1)) ++s3;
13910 indz = compile(s2+1,s3==se2?++s3:s3);
13912 char *s4 = s3+1;
while (s4<se2 && (*s4!=
',' || level[s4-expr._data]!=clevel1)) ++s4;
13913 indc = compile(s3+1,s4==se2?++s4:s4);
13915 char *s5 = s4+1;
while (s5<se2 && (*s5!=
',' || level[s5-expr._data]!=clevel1)) ++s5;
13916 interpolation = compile(s4+1,s5==se2?++s5:s5);
13917 if (s5<se1) borders = compile(s5+1,se1);
13923 _cimg_mp_opcode6(47,indx,indy,indz,indc,interpolation,borders);
13925 if (!std::strncmp(ss,
"min(",4) || !std::strncmp(ss,
"max(",4)) {
13927 if (mempos>=mem.
size()) mem.
resize(-200,1,1,1,0);
13928 const unsigned int pos = mempos++;
13930 for (
char *s = ss4; s<se; ++s) {
13931 char *ns = s;
while (ns<se && (*ns!=
',' || level[ns-expr._data]!=clevel1) && (*ns!=
')' || level[ns-expr._data]!=clevel)) ++ns;
13936 _cimg_mp_return(pos);
13938 if (!std::strncmp(ss,
"arg(",4)) {
13940 if (mempos>=mem.
size()) mem.
resize(-200,1,1,1,0);
13941 const unsigned int pos = mempos++;
13943 for (
char *s = ss4; s<se; ++s) {
13944 char *ns = s;
while (ns<se && (*ns!=
',' || level[ns-expr._data]!=clevel1) && (*ns!=
')' || level[ns-expr._data]!=clevel)) ++ns;
13949 _cimg_mp_return(pos);
13951 if (!std::strncmp(ss,
"narg(",5)) {
13952 if (*ss5==
')') _cimg_mp_return(0);
13953 unsigned int nb_args = 0;
13954 for (
char *s = ss5; s<se; ++s) {
13955 char *ns = s;
while (ns<se && (*ns!=
',' || level[ns-expr._data]!=clevel1) && (*ns!=
')' || level[ns-expr._data]!=clevel)) ++ns;
13958 if (nb_args==0 || nb_args==1) _cimg_mp_return(nb_args);
13959 if (mempos>=mem.
size()) mem.
resize(-200,1,1,1,0);
13960 const unsigned int pos = mempos++;
13961 mem[pos] = nb_args;
13962 _cimg_mp_return(pos);
13964 if (!std::strncmp(ss,
"isval(",6)) {
13965 char sep = 0, end = 0;
double val = 0;
13966 if (std::sscanf(ss6,
"%lf%c%c",&val,&sep,&end)==2 && sep==
')') _cimg_mp_return(1);
13967 _cimg_mp_return(0);
13969 if (!std::strncmp(ss,
"isnan(",6)) _cimg_mp_opcode1(50,compile(ss6,se1));
13970 if (!std::strncmp(ss,
"isinf(",6)) _cimg_mp_opcode1(51,compile(ss6,se1));
13971 if (!std::strncmp(ss,
"isint(",6)) _cimg_mp_opcode1(52,compile(ss6,se1));
13972 if (!std::strncmp(ss,
"isbool(",7)) _cimg_mp_opcode1(53,compile(ss7,se1));
13973 if (!std::strncmp(ss,
"rol(",4) || !std::strncmp(ss,
"ror(",4)) {
13974 unsigned int value = 0, nb = 1;
13975 char *s1 = ss4;
while (s1<se2 && (*s1!=
',' || level[s1-expr._data]!=clevel1)) ++s1;
13976 value = compile(ss4,s1==se2?++s1:s1);
13978 char *s2 = s1+1;
while (s2<se2 && (*s2!=
',' || level[s2-expr._data]!=clevel1)) ++s2;
13979 nb = compile(s1+1,se1);
13981 _cimg_mp_opcode2(*ss2==
'l'?54:55,value,nb);
13984 if (!std::strncmp(ss,
"sinc(",5)) _cimg_mp_opcode1(56,compile(ss5,se1));
13985 if (!std::strncmp(ss,
"int(",4)) _cimg_mp_opcode1(70,compile(ss4,se1));
13989 CImg<charT> variable_name(ss,(
unsigned int)(se-ss+1));
13990 variable_name.
back() = 0;
13991 for (
unsigned int i = 0; i<mempos; ++i)
if (label[i]._data && !std::strcmp(variable_name,label[i])) _cimg_mp_return(i);
13994 "CImg<%s>::%s(): Invalid item '%s' in specified expression '%s'.\n",
13996 variable_name._data,expr._data);
14002 return mem[opcode(2)] +
cimg::rand()*(mem[opcode(3)]-mem[opcode(2)]);
14008 return (
double)reference.atXYZC((
int)mem[8],(
int)mem[9],(
int)mem[10],(
int)mem[11],0);
14011 return mem[8]/reference.width();
14014 return mem[9]/reference.height();
14017 return mem[10]/reference.depth();
14020 return mem[11]/reference.spectrum();
14022 double mp_equal() {
14023 return mem[opcode[2]];
14025 double mp_logical_and() {
14026 return (
double)((
bool)mem[opcode(2)] && (
bool)mem[opcode(3)]);
14028 double mp_logical_or() {
14029 return (
double)((
bool)mem[opcode(2)] || (
bool)mem[opcode(3)]);
14031 double mp_infeq() {
14032 return (
double)(mem[opcode(2)]<=mem[opcode(3)]);
14034 double mp_supeq() {
14035 return (
double)(mem[opcode(2)]>=mem[opcode(3)]);
14037 double mp_noteq() {
14038 return (
double)(mem[opcode(2)]!=mem[opcode(3)]);
14041 return (
double)(mem[opcode(2)]==mem[opcode(3)]);
14044 return (
double)(mem[opcode(2)]<mem[opcode(3)]);
14047 return (
double)(mem[opcode(2)]>mem[opcode(3)]);
14050 return mem[opcode(2)] + mem[opcode(3)];
14053 return mem[opcode(2)] - mem[opcode(3)];
14056 return mem[opcode(2)] * mem[opcode(3)];
14059 return mem[opcode(2)] / mem[opcode(3)];
14061 double mp_minus() {
14062 return -mem[opcode(2)];
14065 return !mem[opcode(2)];
14067 double mp_logical_not() {
14068 return !mem[opcode(2)];
14070 double mp_bitwise_not() {
14071 return ~(
unsigned long)mem[opcode(2)];
14073 double mp_modulo() {
14074 return cimg::mod(mem[opcode(2)],mem[opcode(3)]);
14076 double mp_bitwise_and() {
14077 return ((
unsigned long)mem[opcode(2)] & (
unsigned long)mem[opcode(3)]);
14079 double mp_bitwise_or() {
14080 return ((
unsigned long)mem[opcode(2)] | (
unsigned long)mem[opcode(3)]);
14083 return std::pow(mem[opcode(2)],mem[opcode(3)]);
14086 return std::sin(mem[opcode(2)]);
14089 return std::cos(mem[opcode(2)]);
14092 return std::tan(mem[opcode(2)]);
14095 return std::asin(mem[opcode(2)]);
14098 return std::acos(mem[opcode(2)]);
14101 return std::atan(mem[opcode(2)]);
14104 return std::sinh(mem[opcode(2)]);
14107 return std::cosh(mem[opcode(2)]);
14110 return std::tanh(mem[opcode(2)]);
14112 double mp_log10() {
14113 return std::log10(mem[opcode(2)]);
14119 return std::log(mem[opcode(2)]);
14122 return std::exp(mem[opcode(2)]);
14125 return std::sqrt(mem[opcode(2)]);
14133 double mp_atan2() {
14134 return std::atan2(mem[opcode(2)],mem[opcode(3)]);
14137 return mem[opcode(2)]?mem[opcode(3)]:mem[opcode(4)];
14139 double mp_round() {
14140 return cimg::round(mem[opcode(2)],mem[opcode(3)],(
int)mem[opcode(4)]);
14142 double mp_ixyzc() {
14143 const int i = (int)mem[opcode(6)], b = (int)mem[opcode(7)];
14145 if (b==2)
return (
double)reference.atXYZC(
cimg::mod((
int)mem[opcode(2)],reference.width()),
14146 cimg::mod((
int)mem[opcode(3)],reference.height()),
14147 cimg::mod((
int)mem[opcode(4)],reference.depth()),
14148 cimg::mod((
int)mem[opcode(5)],reference.spectrum()));
14149 if (b==1)
return (
double)reference.atXYZC((
int)mem[opcode(2)],
14150 (
int)mem[opcode(3)],
14151 (
int)mem[opcode(4)],
14152 (
int)mem[opcode(5)]);
14153 return (
double)reference.atXYZC((
int)mem[opcode(2)],
14154 (
int)mem[opcode(3)],
14155 (
int)mem[opcode(4)],
14156 (
int)mem[opcode(5)],0);
14158 if (b==2)
return (
double)reference.linear_atXYZC(
cimg::mod((
float)mem[opcode(2)],(
float)reference.width()),
14159 cimg::mod((
float)mem[opcode(3)],(float)reference.height()),
14160 cimg::mod((
float)mem[opcode(4)],(float)reference.depth()),
14161 cimg::mod((
float)mem[opcode(5)],(float)reference.spectrum()));
14162 if (b==1)
return (
double)reference.linear_atXYZC((
float)mem[opcode(2)],
14163 (
float)mem[opcode(3)],
14164 (
float)mem[opcode(4)],
14165 (
float)mem[opcode(5)]);
14166 return (
double)reference.linear_atXYZC((
float)mem[opcode(2)],
14167 (
float)mem[opcode(3)],
14168 (
float)mem[opcode(4)],
14169 (
float)mem[opcode(5)],0);
14173 double val = mem[opcode(2)];
14174 for (
unsigned int i = 3; i<opcode._height; ++i) val =
cimg::min(val,mem[opcode(i)]);
14178 double val = mem[opcode(2)];
14179 for (
unsigned int i = 3; i<opcode._height; ++i) val =
cimg::max(val,mem[opcode(i)]);
14182 double mp_isnan() {
14183 const double val = mem[opcode(2)];
14184 return !(val==val);
14186 double mp_isinf() {
14187 const double val = mem[opcode(2)];
14188 return val==(val+1);
14190 double mp_isint() {
14191 const double val = mem[opcode(2)];
14192 return (
double)(
cimg::mod(val,1.0)==0);
14194 double mp_isbool() {
14195 const double val = mem[opcode(2)];
14196 return (val==0.0 || val==1.0);
14199 return cimg::rol(mem[opcode(2)],(
unsigned int)mem[opcode(3)]);
14202 return cimg::ror(mem[opcode(2)],(
unsigned int)mem[opcode(3)]);
14205 return (
long)mem[opcode(2)]<<(
unsigned int)mem[opcode(3)];
14208 return (
long)mem[opcode(2)]>>(
unsigned int)mem[opcode(3)];
14214 if (!reference_stats) reference.get_stats().move_to(reference_stats);
14215 return reference_stats?reference_stats[0]:0;
14218 if (!reference_stats) reference.get_stats().move_to(reference_stats);
14219 return reference_stats?reference_stats[1]:0;
14222 if (!reference_stats) reference.get_stats().move_to(reference_stats);
14223 return reference_stats?reference_stats[2]:0;
14226 if (!reference_stats) reference.get_stats().move_to(reference_stats);
14227 return reference_stats?reference_stats[3]:0;
14230 if (!reference_stats) reference.get_stats().move_to(reference_stats);
14231 return reference_stats?reference_stats[4]:0;
14234 if (!reference_stats) reference.get_stats().move_to(reference_stats);
14235 return reference_stats?reference_stats[5]:0;
14238 if (!reference_stats) reference.get_stats().move_to(reference_stats);
14239 return reference_stats?reference_stats[6]:0;
14242 if (!reference_stats) reference.get_stats().move_to(reference_stats);
14243 return reference_stats?reference_stats[7]:0;
14246 if (!reference_stats) reference.get_stats().move_to(reference_stats);
14247 return reference_stats?reference_stats[8]:0;
14250 if (!reference_stats) reference.get_stats().move_to(reference_stats);
14251 return reference_stats?reference_stats[9]:0;
14254 if (!reference_stats) reference.get_stats().move_to(reference_stats);
14255 return reference_stats?reference_stats[10]:0;
14258 if (!reference_stats) reference.get_stats().move_to(reference_stats);
14259 return reference_stats?reference_stats[11]:0;
14262 const int _ind = (int)mem[opcode(2)];
14263 const unsigned int nb_args = opcode._height-2, ind = _ind<0?_ind+nb_args:(
unsigned int)_ind;
14264 if (ind>=nb_args)
return 0;
14265 return mem[opcode(ind+2)];
14268 return (
double)(long)mem[opcode(2)];
14272 double eval(
const double x,
const double y,
const double z,
const double c) {
14274 const mp_func mp_funcs[] = {
14275 &_cimg_math_parser::mp_u,
14276 &_cimg_math_parser::mp_g,
14277 &_cimg_math_parser::mp_i,
14278 &_cimg_math_parser::mp_xw,
14279 &_cimg_math_parser::mp_yh,
14280 &_cimg_math_parser::mp_zd,
14281 &_cimg_math_parser::mp_cs,
14282 &_cimg_math_parser::mp_equal,
14283 &_cimg_math_parser::mp_logical_or,
14284 &_cimg_math_parser::mp_logical_and,
14285 &_cimg_math_parser::mp_bitwise_or,
14286 &_cimg_math_parser::mp_bitwise_and,
14287 &_cimg_math_parser::mp_noteq,
14288 &_cimg_math_parser::mp_eqeq,
14289 &_cimg_math_parser::mp_infeq,
14290 &_cimg_math_parser::mp_supeq,
14291 &_cimg_math_parser::mp_inf,
14292 &_cimg_math_parser::mp_sup,
14293 &_cimg_math_parser::mp_lsl,
14294 &_cimg_math_parser::mp_lsr,
14295 &_cimg_math_parser::mp_sub,
14296 &_cimg_math_parser::mp_add,
14297 &_cimg_math_parser::mp_mul,
14298 &_cimg_math_parser::mp_div,
14299 &_cimg_math_parser::mp_modulo,
14300 &_cimg_math_parser::mp_pow,
14301 &_cimg_math_parser::mp_minus,
14302 &_cimg_math_parser::mp_logical_not,
14303 &_cimg_math_parser::mp_bitwise_not,
14304 &_cimg_math_parser::mp_sin,
14305 &_cimg_math_parser::mp_cos,
14306 &_cimg_math_parser::mp_tan,
14307 &_cimg_math_parser::mp_asin,
14308 &_cimg_math_parser::mp_acos,
14309 &_cimg_math_parser::mp_atan,
14310 &_cimg_math_parser::mp_sinh,
14311 &_cimg_math_parser::mp_cosh,
14312 &_cimg_math_parser::mp_tanh,
14313 &_cimg_math_parser::mp_log10,
14314 &_cimg_math_parser::mp_log,
14315 &_cimg_math_parser::mp_exp,
14316 &_cimg_math_parser::mp_sqrt,
14317 &_cimg_math_parser::mp_sign,
14318 &_cimg_math_parser::mp_abs,
14319 &_cimg_math_parser::mp_atan2,
14320 &_cimg_math_parser::mp_if,
14321 &_cimg_math_parser::mp_round,
14322 &_cimg_math_parser::mp_ixyzc,
14323 &_cimg_math_parser::mp_min,
14324 &_cimg_math_parser::mp_max,
14325 &_cimg_math_parser::mp_isnan,
14326 &_cimg_math_parser::mp_isinf,
14327 &_cimg_math_parser::mp_isint,
14328 &_cimg_math_parser::mp_isbool,
14329 &_cimg_math_parser::mp_rol,
14330 &_cimg_math_parser::mp_ror,
14331 &_cimg_math_parser::mp_sinc,
14332 &_cimg_math_parser::mp_im,
14333 &_cimg_math_parser::mp_iM,
14334 &_cimg_math_parser::mp_ia,
14335 &_cimg_math_parser::mp_iv,
14336 &_cimg_math_parser::mp_xm,
14337 &_cimg_math_parser::mp_ym,
14338 &_cimg_math_parser::mp_zm,
14339 &_cimg_math_parser::mp_cm,
14340 &_cimg_math_parser::mp_xM,
14341 &_cimg_math_parser::mp_yM,
14342 &_cimg_math_parser::mp_zM,
14343 &_cimg_math_parser::mp_cM,
14344 &_cimg_math_parser::mp_arg,
14345 &_cimg_math_parser::mp_int,
14346 &_cimg_math_parser::mp_log2
14349 if (!mem)
return 0;
14350 mem[8] = x; mem[9] = y; mem[10] = z; mem[11] = c;
14351 opcode._is_shared =
true; opcode._width = opcode._depth = opcode._spectrum = 1;
14352 cimglist_for(code,l) {
14354 opcode._data = op._data; opcode._height = op._height;
14355 mem[opcode(1)] = (this->*mp_funcs[opcode[0]])();
14357 return mem[result];
14375 cimg_for(*
this,ptrd,T) {
const T val = *ptrd; *ptrd = (T)(val*val); };
14398 cimg_for(*
this,ptrd,T) *ptrd = (T)std::sqrt((
double)*ptrd);
14415 cimg_for(*
this,ptrd,T) *ptrd = (T)std::exp((
double)*ptrd);
14432 cimg_for(*
this,ptrd,T) *ptrd = (T)std::log((
double)*ptrd);
14449 cimg_for(*
this,ptrd,T) *ptrd = (T)
cimg::log2((
double)*ptrd);
14466 cimg_for(*
this,ptrd,T) *ptrd = (T)std::log10((
double)*ptrd);
14483 cimg_for(*
this,ptrd,T) *ptrd =
cimg::abs(*ptrd);
14504 cimg_for(*
this,ptrd,T) *ptrd =
cimg::sign(*ptrd);
14522 cimg_for(*
this,ptrd,T) *ptrd = (T)std::cos((
double)*ptrd);
14540 cimg_for(*
this,ptrd,T) *ptrd = (T)std::sin((
double)*ptrd);
14558 cimg_for(*
this,ptrd,T) *ptrd = (T)
cimg::sinc((
double)*ptrd);
14576 cimg_for(*
this,ptrd,T) *ptrd = (T)std::tan((
double)*ptrd);
14593 cimg_for(*
this,ptrd,T) *ptrd = (T)std::cosh((
double)*ptrd);
14610 cimg_for(*
this,ptrd,T) *ptrd = (T)std::sinh((
double)*ptrd);
14627 cimg_for(*
this,ptrd,T) *ptrd = (T)std::tanh((
double)*ptrd);
14644 cimg_for(*
this,ptrd,T) *ptrd = (T)std::acos((
double)*ptrd);
14661 cimg_for(*
this,ptrd,T) *ptrd = (T)std::asin((
double)*ptrd);
14678 cimg_for(*
this,ptrd,T) *ptrd = (T)std::atan((
double)*ptrd);
14703 template<
typename t>
14705 const unsigned long siz =
size(), isiz = img.size();
14708 T *ptrd = _data, *
const ptre = _data + siz;
14709 if (siz>isiz)
for (
unsigned long n = siz/isiz; n; --n)
14710 for (
const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs<ptrs_end; ++ptrd) *ptrd = (T)std::atan2((
double)*ptrd,(double)*(ptrs++));
14711 for (
const t *ptrs = img._data; ptrd<ptre; ++ptrd) *ptrd = (T)std::atan2((
double)*ptrd,(double)*(ptrs++));
14717 template<
typename t>
14738 template<
typename t>
14740 const unsigned long siz =
size(), isiz = img.size();
14743 T *ptrd = _data, *
const ptre = _data + siz;
14744 if (siz>isiz)
for (
unsigned long n = siz/isiz; n; --n)
14745 for (
const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs<ptrs_end; ++ptrd) *ptrd = (T)(*ptrd * *(ptrs++));
14746 for (
const t *ptrs = img._data; ptrd<ptre; ++ptrd) *ptrd = (T)(*ptrd * *(ptrs++));
14752 template<
typename t>
14761 template<
typename t>
14763 const unsigned long siz =
size(), isiz = img.size();
14766 T *ptrd = _data, *
const ptre = _data + siz;
14767 if (siz>isiz)
for (
unsigned long n = siz/isiz; n; --n)
14768 for (
const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs<ptrs_end; ++ptrd) *ptrd = (T)(*ptrd / *(ptrs++));
14769 for (
const t *ptrs = img._data; ptrd<ptre; ++ptrd) *ptrd = (T)(*ptrd / *(ptrs++));
14775 template<
typename t>
14797 if (p==0)
return fill(1);
14798 if (p==0.5) { cimg_for(*
this,ptrd,T) {
const T val = *ptrd; *ptrd = (T)std::sqrt((
double)val); }
return *
this; }
14799 if (p==1)
return *
this;
14800 if (p==2) { cimg_for(*
this,ptrd,T) {
const T val = *ptrd; *ptrd = val*val; }
return *
this; }
14801 if (p==3) { cimg_for(*
this,ptrd,T) {
const T val = *ptrd; *ptrd = val*val*val; }
return *
this; }
14802 if (p==4) { cimg_for(*
this,ptrd,T) {
const T val = *ptrd; *ptrd = val*val*val*val; }
return *
this; }
14803 cimg_for(*
this,ptrd,T) *ptrd = (T)std::pow((
double)*ptrd,p);
14820 const CImg<T> _base = std::strstr(expression,
"i(")?+*
this:
CImg<T>(), &base = _base?_base:*
this;
14821 _cimg_math_parser mp(base,expression,
"pow");
14823 cimg_forXYZC(*
this,x,y,z,c) { *ptrd = (T)std::pow((
double)*ptrd,mp.eval(x,y,z,c)); ++ptrd; }
14827 values.fill(expression,
true);
14830 values.load(expression);
14847 template<
typename t>
14849 const unsigned long siz =
size(), isiz = img.size();
14852 T *ptrd = _data, *
const ptre = _data + siz;
14853 if (siz>isiz)
for (
unsigned long n = siz/isiz; n; --n)
14854 for (
const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs<ptrs_end; ++ptrd) *ptrd = (T)std::pow((
double)*ptrd,(double)(*(ptrs++)));
14855 for (
const t *ptrs = img._data; ptrd<ptre; ++ptrd) *ptrd = (T)std::pow((
double)*ptrd,(double)(*(ptrs++)));
14861 template<
typename t>
14871 cimg_for(*
this,ptrd,T) *ptrd = (T)
cimg::rol(*ptrd,n);
14877 return (+*
this).
rol(n);
14888 const CImg<T> _base = std::strstr(expression,
"i(")?+*
this:
CImg<T>(), &base = _base?_base:*
this;
14889 _cimg_math_parser mp(base,expression,
"rol");
14891 cimg_forXYZC(*
this,x,y,z,c) { *ptrd = (T)
cimg::rol(*ptrd,(
unsigned int)mp.eval(x,y,z,c)); ++ptrd; }
14895 values.fill(expression,
true);
14898 values.load(expression);
14908 return (+*
this).
rol(expression);
14915 template<
typename t>
14917 const unsigned long siz =
size(), isiz = img.size();
14920 T *ptrd = _data, *
const ptre = _data + siz;
14921 if (siz>isiz)
for (
unsigned long n = siz/isiz; n; --n)
14922 for (
const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs<ptrs_end; ++ptrd) *ptrd = (T)
cimg::rol(*ptrd,(
unsigned int)(*(ptrs++)));
14923 for (
const t *ptrs = img._data; ptrd<ptre; ++ptrd) *ptrd = (T)
cimg::rol(*ptrd,(
unsigned int)(*(ptrs++)));
14929 template<
typename t>
14931 return (+*
this).
rol(img);
14939 cimg_for(*
this,ptrd,T) *ptrd = (T)
cimg::ror(*ptrd,n);
14945 return (+*
this).
ror(n);
14956 const CImg<T> _base = std::strstr(expression,
"i(")?+*
this:
CImg<T>(), &base = _base?_base:*
this;
14957 _cimg_math_parser mp(base,expression,
"ror");
14959 cimg_forXYZC(*
this,x,y,z,c) { *ptrd = (T)
cimg::ror(*ptrd,(
unsigned int)mp.eval(x,y,z,c)); ++ptrd; }
14963 values.fill(expression,
true);
14966 values.load(expression);
14976 return (+*
this).
ror(expression);
14983 template<
typename t>
14985 const unsigned long siz =
size(), isiz = img.size();
14988 T *ptrd = _data, *
const ptre = _data + siz;
14989 if (siz>isiz)
for (
unsigned long n = siz/isiz; n; --n)
14990 for (
const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs<ptrs_end; ++ptrd) *ptrd = (T)
cimg::ror(*ptrd,(
unsigned int)(*(ptrs++)));
14991 for (
const t *ptrs = img._data; ptrd<ptre; ++ptrd) *ptrd = (T)
cimg::ror(*ptrd,(
unsigned int)(*(ptrs++)));
14997 template<
typename t>
14999 return (+*
this).
ror(img);
15008 cimg_for(*
this,ptrd,T) *ptrd =
cimg::min(*ptrd,val);
15014 return (+*
this).
min(val);
15022 template<
typename t>
15024 const unsigned long siz =
size(), isiz = img.size();
15027 T *ptrd = _data, *
const ptre = _data + siz;
15028 if (siz>isiz)
for (
unsigned long n = siz/isiz; n; --n)
15029 for (
const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs<ptrs_end; ++ptrd) *ptrd =
cimg::min((T)*(ptrs++),*ptrd);
15030 for (
const t *ptrs = img._data; ptrd<ptre; ++ptrd) *ptrd =
cimg::min((T)*(ptrs++),*ptrd);
15036 template<
typename t>
15050 const CImg<T> _base = std::strstr(expression,
"i(")?+*
this:
CImg<T>(), &base = _base?_base:*
this;
15051 _cimg_math_parser mp(base,expression,
"min");
15053 cimg_forXYZC(*
this,x,y,z,c) { *ptrd = (T)
cimg::min(*ptrd,(T)mp.eval(x,y,z,c)); ++ptrd; }
15055 CImg<T> values(_width,_height,_depth,_spectrum);
15057 values.fill(expression,
true);
15060 values.load(expression);
15079 cimg_for(*
this,ptrd,T) *ptrd =
cimg::max(*ptrd,val);
15085 return (+*
this).
max(val);
15093 template<
typename t>
15095 const unsigned long siz =
size(), isiz = img.size();
15098 T *ptrd = _data, *
const ptre = _data + siz;
15099 if (siz>isiz)
for (
unsigned long n = siz/isiz; n; --n)
15100 for (
const t *ptrs = img._data, *ptrs_end = ptrs + isiz; ptrs<ptrs_end; ++ptrd) *ptrd =
cimg::max((T)*(ptrs++),*ptrd);
15101 for (
const t *ptrs = img._data; ptrd<ptre; ++ptrd) *ptrd =
cimg::max((T)*(ptrs++),*ptrd);
15107 template<
typename t>
15121 const CImg<T> _base = std::strstr(expression,
"i(")?+*
this:
CImg<T>(), &base = _base?_base:*
this;
15122 _cimg_math_parser mp(base,expression,
"max");
15124 cimg_forXYZC(*
this,x,y,z,c) { *ptrd = (T)
cimg::max(*ptrd,(T)mp.eval(x,y,z,c)); ++ptrd; }
15126 CImg<T> values(_width,_height,_depth,_spectrum);
15128 values.fill(expression,
true);
15131 values.load(expression);
15150 "min(): Empty instance.",
15152 T *ptr_min = _data;
15153 T min_value = *ptr_min;
15154 cimg_for(*
this,ptrs,T)
if (*ptrs<min_value) min_value = *(ptr_min=ptrs);
15162 "min(): Empty instance.",
15164 const T *ptr_min = _data;
15165 T min_value = *ptr_min;
15166 cimg_for(*
this,ptrs,T)
if (*ptrs<min_value) min_value = *(ptr_min=ptrs);
15176 "max(): Empty instance.",
15178 T *ptr_max = _data;
15179 T max_value = *ptr_max;
15180 cimg_for(*
this,ptrs,T)
if (*ptrs>max_value) max_value = *(ptr_max=ptrs);
15188 "max(): Empty instance.",
15190 const T *ptr_max = _data;
15191 T max_value = *ptr_max;
15192 cimg_for(*
this,ptrs,T)
if (*ptrs>max_value) max_value = *(ptr_max=ptrs);
15200 template<
typename t>
15204 "min_max(): Empty instance.",
15206 T *ptr_min = _data;
15207 T min_value = *ptr_min, max_value = min_value;
15208 cimg_for(*
this,ptrs,T) {
15209 const T val = *ptrs;
15210 if (val<min_value) { min_value = val; ptr_min = ptrs; }
15211 if (val>max_value) max_value = val;
15213 max_val = (t)max_value;
15218 template<
typename t>
15222 "min_max(): Empty instance.",
15224 const T *ptr_min = _data;
15225 T min_value = *ptr_min, max_value = min_value;
15226 cimg_for(*
this,ptrs,T) {
15227 const T val = *ptrs;
15228 if (val<min_value) { min_value = val; ptr_min = ptrs; }
15229 if (val>max_value) max_value = val;
15231 max_val = (t)max_value;
15239 template<
typename t>
15243 "max_min(): Empty instance.",
15245 T *ptr_max = _data;
15246 T max_value = *ptr_max, min_value = max_value;
15247 cimg_for(*
this,ptrs,T) {
15248 const T val = *ptrs;
15249 if (val>max_value) { max_value = val; ptr_max = ptrs; }
15250 if (val<min_value) min_value = val;
15252 min_val = (t)min_value;
15257 template<
typename t>
15261 "max_min(): Empty instance.",
15263 const T *ptr_max = _data;
15264 T max_value = *ptr_max, min_value = max_value;
15265 cimg_for(*
this,ptrs,T) {
15266 const T val = *ptrs;
15267 if (val>max_value) { max_value = val; ptr_max = ptrs; }
15268 if (val<min_value) min_value = val;
15270 min_val = (t)min_value;
15281 "kth_smallest(): Empty instance.",
15284 unsigned int l = 0, ir =
size() - 1;
15287 if (ir==l+1 && arr[ir]<arr[l])
cimg::swap(arr[l],arr[ir]);
15290 const unsigned int mid = (l + ir)>>1;
15292 if (arr[l]>arr[ir])
cimg::swap(arr[l],arr[ir]);
15293 if (arr[l+1]>arr[ir])
cimg::swap(arr[l+1],arr[ir]);
15294 if (arr[l]>arr[l+1])
cimg::swap(arr[l],arr[l+1]);
15295 unsigned int i = l + 1, j = ir;
15296 const T pivot = arr[l+1];
15298 do ++i;
while (arr[i]<pivot);
15299 do --j;
while (arr[j]>pivot);
15305 if (j>=k) ir = j - 1;
15318 "median(): Empty instance.",
15320 const unsigned int s =
size();
15331 "sum(): Empty instance.",
15334 cimg_for(*
this,ptrs,T) res+=(Tdouble)*ptrs;
15344 "mean(): Empty instance.",
15347 cimg_for(*
this,ptrs,T) res+=(Tdouble)*ptrs;
15361 Tdouble
variance(
const unsigned int variance_method=1)
const {
15371 template<
typename t>
15375 "variance_mean(): Empty instance.",
15378 Tdouble
variance = 0, average = 0;
15379 const unsigned long siz =
size();
15380 switch (variance_method) {
15382 Tdouble S = 0, S2 = 0;
15383 cimg_for(*
this,ptrs,T) {
const Tdouble val = (Tdouble)*ptrs; S+=val; S2+=val*val; }
15384 variance = (S2 - S*S/siz)/siz;
15388 Tdouble S = 0, S2 = 0;
15389 cimg_for(*
this,ptrs,T) {
const Tdouble val = (Tdouble)*ptrs; S+=val; S2+=val*val; }
15390 variance = siz>1?(S2 - S*S/siz)/(siz - 1):0;
15396 const unsigned long siz2 = siz>>1;
15397 const Tdouble med_i = (double)buf[siz2];
15398 cimg_for(buf,ptrs,Tfloat) {
const Tdouble val = (Tdouble)*ptrs; *ptrs = (Tfloat)
cimg::abs(val - med_i); average+=val; }
15400 const Tdouble sig = (Tdouble)(1.4828*buf[siz2]);
15401 variance = sig*sig;
15405 const unsigned long siz2 = siz>>1;
15406 cimg_for(buf,ptrs,Tfloat) {
const Tdouble val = (Tdouble)*ptrs; (*ptrs)=(Tfloat)((*ptrs)*val); average+=val; }
15409 const Tfloat *ptrs = buf._data;
15410 for (
unsigned long j = 0; j<siz2; ++j) a+=(Tdouble)*(ptrs++);
15411 const Tdouble sig = (Tdouble)(2.6477*std::sqrt(a/siz2));
15412 variance = sig*sig;
15415 mean = (t)(average/siz);
15416 return variance>0?variance:0;
15431 "variance_noise(): Empty instance.",
15434 const unsigned long siz =
size();
15435 if (!siz || !_data)
return 0;
15436 if (variance_method>1) {
15439 const Tdouble cste = 1.0/std::sqrt(20.0);
15441 cimg_forC(*
this,c) cimg_for3x3(*
this,x,y,0,c,I,T) {
15442 tmp(x,y,c) = cste*((Tdouble)Inc + (Tdouble)Ipc + (Tdouble)Icn +
15443 (Tdouble)Icp - 4*(Tdouble)Icc);
15446 const Tdouble cste = 1.0/std::sqrt(42.0);
15448 cimg_forC(*
this,c) cimg_for3x3x3(*
this,x,y,z,c,I,T) {
15449 tmp(x,y,z,c) = cste*(
15450 (Tdouble)Incc + (Tdouble)Ipcc + (Tdouble)Icnc + (Tdouble)Icpc +
15451 (Tdouble)Iccn + (Tdouble)Iccp - 6*(Tdouble)Iccc);
15454 return tmp.
variance(variance_method);
15458 Tdouble
variance = 0, S = 0, S2 = 0;
15460 const Tdouble cste = 1.0/std::sqrt(20.0);
15462 cimg_forC(*
this,c) cimg_for3x3(*
this,x,y,0,c,I,T) {
15463 const Tdouble val = cste*((Tdouble)Inc + (Tdouble)Ipc +
15464 (Tdouble)Icn + (Tdouble)Icp - 4*(Tdouble)Icc);
15465 S+=val; S2+=val*val;
15468 const Tdouble cste = 1.0/std::sqrt(42.0);
15470 cimg_forC(*
this,c) cimg_for3x3x3(*
this,x,y,z,c,I,T) {
15471 const Tdouble val = cste *
15472 ((Tdouble)Incc + (Tdouble)Ipcc + (Tdouble)Icnc +
15474 (Tdouble)Iccn + (Tdouble)Iccp - 6*(Tdouble)Iccc);
15475 S+=val; S2+=val*val;
15478 if (variance_method) variance = siz>1?(S2 - S*S/siz)/(siz - 1):0;
15479 else variance = (S2 - S*S/siz)/siz;
15480 return variance>0?variance:0;
15487 template<
typename t>
15489 if (img.size()!=
size())
15491 "MSE(): Instance and specified image (%u,%u,%u,%u,%p) have different dimensions.",
15493 img._width,img._height,img._depth,img._spectrum,img._data);
15495 const t* ptr2 = img._data;
15496 cimg_for(*
this,ptr1,T) {
15497 const Tdouble diff = (Tdouble)*ptr1 - (Tdouble)*(ptr2++);
15500 const unsigned long siz = img.size();
15501 if (siz) vMSE/=siz;
15510 template<
typename t>
15512 const Tdouble vMSE = (Tdouble)std::sqrt(
MSE(img));
15525 double eval(
const char *
const expression,
const double x=0,
const double y=0,
const double z=0,
const double c=0)
const {
15526 static _cimg_math_parser *mp = 0;
15527 if (expression) {
delete mp; mp = 0; mp =
new _cimg_math_parser(*
this,expression,
"eval"); }
15528 return mp?mp->eval(x,y,z,c):0;
15538 const unsigned long siz =
size();
15539 const T *
const odata = _data;
15540 const T *pm = odata, *pM = odata;
15541 Tdouble S = 0, S2 = 0;
15543 cimg_for(*
this,ptrs,T) {
15544 const T val = *ptrs;
15545 const Tdouble _val = (Tdouble)val;
15546 if (val<m) { m = val; pm = ptrs; }
15547 if (val>M) { M = val; pM = ptrs; }
15552 mean_value = S/siz,
15553 _variance_value = variance_method==0?(S2 - S*S/siz)/siz:
15554 (variance_method==1?(siz>1?(S2 - S*S/siz)/(siz - 1):0):
15556 variance_value = _variance_value>0?_variance_value:0;
15558 xm = 0, ym = 0, zm = 0, cm = 0,
15559 xM = 0, yM = 0, zM = 0, cM = 0;
15562 return CImg<Tdouble>(1,12).
fill((Tdouble)m,(Tdouble)M,mean_value,variance_value,
15563 (Tdouble)xm,(Tdouble)ym,(Tdouble)zm,(Tdouble)cm,
15564 (Tdouble)xM,(Tdouble)yM,(Tdouble)zM,(Tdouble)cM);
15589 "magnitude(): Empty instance.",
15592 switch (magnitude_type) {
15594 cimg_for(*
this,ptrs,T) {
const Tdouble val = (Tdouble)
cimg::abs(*ptrs);
if (val>res) res = val; }
15597 cimg_for(*
this,ptrs,T) res+=(Tdouble)
cimg::abs(*ptrs);
15600 cimg_for(*
this,ptrs,T) res+=(Tdouble)
cimg::sqr(*ptrs);
15601 res = (Tdouble)std::sqrt(res);
15613 "trace(): Empty instance.",
15616 cimg_forX(*
this,k) res+=(Tdouble)(*
this)(k,k);
15624 if (
is_empty() || _width!=_height || _depth!=1 || _spectrum!=1)
15626 "det(): Instance is not a square matrix.",
15630 case 1 :
return (Tdouble)((*this)(0,0));
15631 case 2 :
return (Tdouble)((*this)(0,0))*(Tdouble)((*
this)(1,1)) - (Tdouble)((*
this)(0,1))*(Tdouble)((*
this)(1,0));
15634 a = (Tdouble)_data[0], d = (Tdouble)_data[1], g = (Tdouble)_data[2],
15635 b = (Tdouble)_data[3], e = (Tdouble)_data[4], h = (Tdouble)_data[5],
15636 c = (Tdouble)_data[6], f = (Tdouble)_data[7], i = (Tdouble)_data[8];
15637 return i*a*e - a*h*f - i*b*d + b*g*f + c*d*h - c*g*e;
15644 Tdouble res = d?(Tdouble)1:(Tdouble)-1;
15645 cimg_forX(lu,i) res*=lu(i,i);
15656 template<
typename t>
15660 "dot(): Empty instance.",
15664 "dot(): Empty specified image.",
15669 for (
unsigned int off = 0; off<nb; ++off) res+=(Tdouble)_data[off]*(Tdouble)img[off];
15681 if (res._height!=_spectrum) res.
assign(1,_spectrum);
15682 const unsigned long whd = (
unsigned long)_width*_height*_depth;
15683 const T *ptrs =
data(x,y,z);
15684 T *ptrd = res._data;
15685 cimg_forC(*
this,c) { *(ptrd++) = *ptrs; ptrs+=whd; }
15697 const int n = (int)std::sqrt((
double)_spectrum);
15698 const T *ptrs =
data(x,y,z,0);
15699 const unsigned long whd = (
unsigned long)_width*_height*_depth;
15701 T *ptrd = res._data;
15702 cimg_forC(*
this,c) { *(ptrd++) = *ptrs; ptrs+=whd; }
15713 const T *ptrs =
data(x,y,z,0);
15714 const unsigned long whd = (
unsigned long)_width*_height*_depth;
15715 if (_spectrum==6)
return tensor(*ptrs,*(ptrs+whd),*(ptrs+2*whd),*(ptrs+3*whd),*(ptrs+4*whd),*(ptrs+5*whd));
15716 if (_spectrum==3)
return tensor(*ptrs,*(ptrs+whd),*(ptrs+2*whd));
15727 template<
typename t>
15729 if (x<_width && y<_height && z<_depth) {
15730 const t *ptrs = vec._data;
15731 const unsigned long whd = (
unsigned long)_width*_height*_depth;
15732 T *ptrd =
data(x,y,z);
15733 for (
unsigned int k =
cimg::min((
unsigned int)vec.size(),_spectrum); k; --k) { *ptrd = (T)*(ptrs++); ptrd+=whd; }
15745 template<
typename t>
15757 template<
typename t>
15759 T *ptrd =
data(x,y,z,0);
15760 const unsigned long siz = (
unsigned long)_width*_height*_depth;
15761 if (ten._height==2) {
15762 *ptrd = (T)ten[0]; ptrd+=siz;
15763 *ptrd = (T)ten[1]; ptrd+=siz;
15767 *ptrd = (T)ten[0]; ptrd+=siz;
15768 *ptrd = (T)ten[1]; ptrd+=siz;
15769 *ptrd = (T)ten[2]; ptrd+=siz;
15770 *ptrd = (T)ten[4]; ptrd+=siz;
15771 *ptrd = (T)ten[5]; ptrd+=siz;
15794 const unsigned long siz =
size();
15797 case 4 : _width = _height = 2;
break;
15798 case 9 : _width = _height = 3;
break;
15799 case 16 : _width = _height = 4;
break;
15800 case 25 : _width = _height = 5;
break;
15801 case 36 : _width = _height = 6;
break;
15802 case 49 : _width = _height = 7;
break;
15803 case 64 : _width = _height = 8;
break;
15804 case 81 : _width = _height = 9;
break;
15805 case 100 : _width = _height = 10;
break;
15807 unsigned long i = 11, i2 = i*i;
15808 while (i2<siz) { i2+=2*i + 1; ++i; }
15809 if (i2==siz) _width = _height = i;
15811 "matrix(): Invalid instance size %u (should be a square integer).",
15821 return (+*
this).
matrix();
15834 const unsigned long siz =
size();
15839 res(0,0) = (*this)(0);
15840 res(1,0) = res(0,1) = (*this)(1);
15841 res(1,1) = (*this)(2);
15845 res(0,0) = (*this)(0);
15846 res(1,0) = res(0,1) = (*this)(1);
15847 res(2,0) = res(0,2) = (*this)(2);
15848 res(1,1) = (*this)(3);
15849 res(2,1) = res(1,2) = (*this)(4);
15850 res(2,2) = (*this)(5);
15854 "tensor(): Invalid instance size (does not define a 1x1, 2x2 or 3x3 tensor).",
15872 cimg_foroff(*
this,off) res(off,off) = (*this)(off);
15896 const unsigned int siz =
size() - 1;
15899 const Tdouble delta = (Tdouble)a1 - (Tdouble)a0;
15900 cimg_foroff(*
this,l) *(ptr++) = (T)(a0 + delta*l/siz);
15915 if (_width==1) { _width = _height; _height = 1;
return *
this; }
15916 if (_height==1) { _height = _width; _width = 1;
return *
this; }
15917 if (_width==_height) {
15918 cimg_forYZC(*
this,y,z,c)
for (
int x = y; x<
width(); ++x)
cimg::swap((*
this)(x,y,z,c),(*
this)(y,x,z,c));
15934 template<
typename t>
15936 if (_width!=1 || _height<3 || img._width!=1 || img._height<3)
15938 "cross(): Instance and/or specified image (%u,%u,%u,%u,%p) are not 3d vectors.",
15940 img._width,img._height,img._depth,img._spectrum,img._data);
15942 const T x = (*this)[0], y = (*this)[1], z = (*this)[2];
15943 (*this)[0] = (T)(y*img[2] - z*img[1]);
15944 (*this)[1] = (T)(z*img[0] - x*img[2]);
15945 (*this)[2] = (T)(x*img[1] - y*img[0]);
15950 template<
typename t>
15962 if (_width!=_height || _depth!=1 || _spectrum!=1)
15964 "invert(): Instance is not a square matrix.",
15966 #ifdef cimg_use_lapack
15967 int INFO = (int)use_LU, N = _width, LWORK = 4*N, *
const IPIV =
new int[N];
15969 *
const lapA =
new Tfloat[N*N],
15970 *
const WORK =
new Tfloat[LWORK];
15971 cimg_forXY(*
this,k,l) lapA[k*N+l] = (Tfloat)((*
this)(k,l));
15972 cimg::getrf(N,lapA,IPIV,INFO);
15975 "invert(): LAPACK function dgetrf_() returned error code %d.",
15979 cimg::getri(N,lapA,IPIV,WORK,LWORK,INFO);
15982 "invert(): LAPACK function dgetri_() returned error code %d.",
15986 if (!INFO) cimg_forXY(*
this,k,l) (*this)(k,l) = (T)(lapA[k*N+l]);
else fill(0);
15987 delete[] IPIV;
delete[] lapA;
delete[] WORK;
15989 const double dete = _width>3?-1.0:
det();
15990 if (dete!=0.0 && _width==2) {
15992 a = _data[0], c = _data[1],
15993 b = _data[2], d = _data[3];
15994 _data[0] = (T)(d/dete); _data[1] = (T)(-c/dete);
15995 _data[2] = (T)(-b/dete); _data[3] = (T)(a/dete);
15996 }
else if (dete!=0.0 && _width==3) {
15998 a = _data[0], d = _data[1], g = _data[2],
15999 b = _data[3], e = _data[4], h = _data[5],
16000 c = _data[6], f = _data[7], i = _data[8];
16001 _data[0] = (T)((i*e-f*h)/dete), _data[1] = (T)((g*f-i*d)/dete), _data[2] = (T)((d*h-g*e)/dete);
16002 _data[3] = (T)((h*c-i*b)/dete), _data[4] = (T)((i*a-c*g)/dete), _data[5] = (T)((g*b-a*h)/dete);
16003 _data[6] = (T)((b*f-e*c)/dete), _data[7] = (T)((d*c-a*f)/dete), _data[8] = (T)((a*e-d*b)/dete);
16009 cimg_forX(*
this,j) {
16012 col._solve(A,indx);
16013 cimg_forX(*
this,i) (*this)(j,i) = (T)col(i);
16016 CImg<Tfloat> U(_width,_width), S(1,_width), V(_width,_width);
16019 cimg_forY(S,k)
if (S[k]!=0) S[k]=1/S[k];
16044 const Tfloat tolerance = (
sizeof(Tfloat)<=4?5.96e-8f:1.11e-16f)*
cimg::max(_width,_height)*S.max();
16046 const Tfloat s = S(x), invs = s>tolerance?1/s:(Tfloat)0;
16047 cimg_forY(V,y) V(x,y)*=invs;
16049 return V*U.transpose();
16057 template<
typename t>
16059 if (_width!=1 || _depth!=1 || _spectrum!=1 || _height!=A._height || A._depth!=1 || A._spectrum!=1)
16061 "solve(): Instance and specified matrix (%u,%u,%u,%u,%p) have incompatible dimensions.",
16063 A._width,A._height,A._depth,A._spectrum,A._data);
16064 typedef _cimg_Ttfloat Ttfloat;
16065 if (A._width==A._height) {
16066 #ifdef cimg_use_lapack
16068 int INFO, N = _height, LWORK = 4*N, *
const IPIV =
new int[N];
16070 *
const lapA =
new Ttfloat[N*N],
16071 *
const lapB =
new Ttfloat[N],
16072 *
const WORK =
new Ttfloat[LWORK];
16073 cimg_forXY(A,k,l) lapA[k*N+l] = (Ttfloat)(A(k,l));
16074 cimg_forY(*
this,i) lapB[i] = (Ttfloat)((*
this)(i));
16075 cimg::getrf(N,lapA,IPIV,INFO);
16078 "solve(): LAPACK library function dgetrf_() returned error code %d.",
16083 cimg::getrs(TRANS,N,lapA,IPIV,lapB,INFO);
16086 "solve(): LAPACK library function dgetrs_() returned error code %d.",
16090 if (!INFO) cimg_forY(*
this,i) (*this)(i) = (T)(lapB[i]);
else fill(0);
16091 delete[] IPIV;
delete[] lapA;
delete[] lapB;
delete[] WORK;
16100 #ifdef cimg_use_lapack
16102 int INFO, N = A._width, M = A._height, LWORK = -1, LDA = M, LDB = M, NRHS = _width;
16103 Ttfloat WORK_QUERY;
16105 *
const lapA =
new Ttfloat[M*N],
16106 *
const lapB =
new Ttfloat[M*NRHS];
16107 cimg::sgels(TRANS, M, N, NRHS, lapA, LDA, lapB, LDB, &WORK_QUERY, LWORK, INFO);
16108 LWORK = (int) WORK_QUERY;
16109 Ttfloat *
const WORK =
new Ttfloat[LWORK];
16110 cimg_forXY(A,k,l) lapA[k*M+l] = (Ttfloat)(A(k,l));
16111 cimg_forXY(*
this,k,l) lapB[k*M+l] = (Ttfloat)((*
this)(k,l));
16112 cimg::sgels(TRANS, M, N, NRHS, lapA, LDA, lapB, LDB, WORK, LWORK, INFO);
16115 "solve(): LAPACK library function sgels() returned error code %d.",
16120 cimg_forXY(*
this,k,l) (*this)(k,l) = (T) lapB[k*M+l];
16122 assign(A.get_pseudoinvert()*(*this));
16123 delete[] lapA;
delete[] lapB;
delete[] WORK;
16125 assign(A.get_pseudoinvert()*(*this));
16132 template<
typename t>
16137 template<
typename t,
typename ti>
16139 typedef _cimg_Ttfloat Ttfloat;
16140 const int N =
size();
16143 for (
int i = 0; i<N; ++i) {
16144 const int ip = (int)indx[i];
16145 Ttfloat sum = (*this)(ip);
16146 (*this)(ip) = (*
this)(i);
16147 if (ii>=0)
for (
int j = ii; j<=i-1; ++j) sum-=A(j,i)*(*this)(j);
16148 else if (sum!=0) ii = i;
16149 (*this)(i) = (T)sum;
16151 for (
int i = N - 1; i>=0; --i) {
16153 for (
int j = i + 1; j<N; ++j) sum-=A(j,i)*(*this)(j);
16154 (*this)(i) = (T)(sum/A(i,i));
16166 template<
typename t>
16168 const unsigned int siz = (int)
size();
16169 if (A._width!=3 || A._height!=siz)
16171 "solve_tridiagonal(): Instance and tridiagonal matrix "
16172 "(%u,%u,%u,%u,%p) have incompatible dimensions.",
16174 A._width,A._height,A._depth,A._spectrum,A._data);
16175 typedef _cimg_Ttfloat Ttfloat;
16176 const Ttfloat epsilon = 1e-4;
16178 for (
int i = 1; i<(int)siz; ++i) {
16179 const Ttfloat m = A(0,i)/(B[i-1]?B[i-1]:epsilon);
16180 B[i] -= m*A(2,i-1);
16183 (*this)[siz-1] = (T)(V[siz-1]/(B[siz-1]?B[siz-1]:epsilon));
16184 for (
int i = (
int)siz - 2; i>=0; --i) (*
this)[i] = (T)((V[i] - A(2,i)*(*this)[i+1])/(B[i]?B[i]:epsilon));
16189 template<
typename t>
16199 template<
typename t>
16201 if (
is_empty()) { val.assign(); vec.assign(); }
16203 if (_width!=_height || _depth>1 || _spectrum>1)
16205 "eigen(): Instance is not a square matrix.",
16208 if (val.size()<(
unsigned long)_width) val.assign(1,_width);
16209 if (vec.size()<(
unsigned long)_width*_width) vec.assign(_width,_width);
16211 case 1 : { val[0] = (t)(*
this)[0]; vec[0] = (t)1; }
break;
16213 const double a = (*this)[0], b = (*this)[1], c = (*this)[2], d = (*this)[3], e = a + d;
16214 double f = e*e - 4*(a*d - b*c);
16217 "eigen(): Complex eigenvalues found.",
16221 const double l1 = 0.5*(e-f), l2 = 0.5*(e+f);
16222 const double theta1 = std::atan2(l2-a,b), theta2 = std::atan2(l1-a,b);
16225 vec(0,0) = (t)std::cos(theta1);
16226 vec(0,1) = (t)std::sin(theta1);
16227 vec(1,0) = (t)std::cos(theta2);
16228 vec(1,1) = (t)std::sin(theta2);
16232 "eigen(): Eigenvalues computation of general matrices is limited to 2x2 matrices.",
16245 eigen(res[0],res[1]);
16254 template<
typename t>
16256 if (
is_empty()) { val.assign(); vec.assign(); }
16258 #ifdef cimg_use_lapack
16259 char JOB =
'V', UPLO =
'U';
16260 int N = _width, LWORK = 4*N, INFO;
16262 *
const lapA =
new Tfloat[N*N],
16263 *
const lapW =
new Tfloat[N],
16264 *
const WORK =
new Tfloat[LWORK];
16265 cimg_forXY(*
this,k,l) lapA[k*N+l] = (Tfloat)((*
this)(k,l));
16266 cimg::syev(JOB,UPLO,N,lapA,lapW,WORK,LWORK,INFO);
16269 "symmetric_eigen(): LAPACK library function dsyev_() returned error code %d.",
16276 cimg_forY(val,i) val(i) = (T)lapW[N-1-i];
16277 cimg_forXY(vec,k,l) vec(k,l) = (T)(lapA[(N-1-k)*N+l]);
16278 }
else { val.fill(0); vec.fill(0); }
16279 delete[] lapA;
delete[] lapW;
delete[] WORK;
16281 if (_width!=_height || _depth>1 || _spectrum>1)
16283 "eigen(): Instance is not a square matrix.",
16286 val.assign(1,_width);
16287 if (vec._data) vec.assign(_width,_width);
16290 if (_width==2) { vec[1] = -vec[2]; vec[3] = vec[0]; }
16294 SVD(vec,val,V,
false);
16295 bool is_ambiguous =
false;
16298 if (val[p]>eig) eig = (float)val[p];
16300 cimg_forY(vec,y) scal+=vec(p,y)*V(p,y);
16301 if (
cimg::abs(scal)<0.9f) is_ambiguous =
true;
16302 if (scal<0) val[p] = -val[p];
16304 if (is_ambiguous) {
16306 SVD(vec,val,V,
false,40,eig);
16311 val.sort(permutations,
false);
16313 cimg_forY(permutations,y) tmp(y) = vec(permutations(y),k);
16314 std::memcpy(vec.data(0,k),tmp._data,
sizeof(t)*_width);
16336 template<
typename t>
16338 permutations.assign(_width,_height,_depth,_spectrum);
16340 cimg_foroff(permutations,off) permutations[off] = (t)off;
16341 return _quicksort(0,
size()-1,permutations,is_increasing,
true);
16345 template<
typename t>
16347 return (+*
this).
sort(permutations,is_increasing);
16365 _quicksort(0,
size()-1,perm,is_increasing,
false);
16369 get_crop(0,0,0,0,_width-1,0,0,0).sort(perm,is_increasing);
16371 cimg_forXYZC(*
this,x,y,z,c) (*this)(x,y,z,c) = img(perm[x],y,z,c);
16375 get_crop(0,0,0,0,0,_height-1,0,0).sort(perm,is_increasing);
16377 cimg_forXYZC(*
this,x,y,z,c) (*this)(x,y,z,c) = img(x,perm[y],z,c);
16381 get_crop(0,0,0,0,0,0,_depth-1,0).sort(perm,is_increasing);
16383 cimg_forXYZC(*
this,x,y,z,c) (*this)(x,y,z,c) = img(x,y,perm[z],c);
16387 get_crop(0,0,0,0,0,0,0,_spectrum-1).sort(perm,is_increasing);
16389 cimg_forXYZC(*
this,x,y,z,c) (*this)(x,y,z,c) = img(x,y,z,perm[c]);
16393 "sort(): Invalid specified axis '%c' "
16394 "(should be { x | y | z | c }).",
16395 cimg_instance,axis);
16402 return (+*
this).
sort(is_increasing,axis);
16405 template<
typename t>
16406 CImg<T>& _quicksort(
const int indm,
const int indM,
CImg<t>& permutations,
const bool is_increasing,
const bool is_permutations) {
16408 const int mid = (indm + indM)/2;
16409 if (is_increasing) {
16410 if ((*
this)[indm]>(*this)[mid]) {
16411 cimg::swap((*
this)[indm],(*
this)[mid]);
if (is_permutations)
cimg::swap(permutations[indm],permutations[mid]);
16413 if ((*
this)[mid]>(*
this)[indM]) {
16414 cimg::swap((*
this)[indM],(*
this)[mid]);
if (is_permutations)
cimg::swap(permutations[indM],permutations[mid]);
16416 if ((*
this)[indm]>(*
this)[mid]) {
16417 cimg::swap((*
this)[indm],(*
this)[mid]);
if (is_permutations)
cimg::swap(permutations[indm],permutations[mid]);
16420 if ((*
this)[indm]<(*
this)[mid]) {
16421 cimg::swap((*
this)[indm],(*
this)[mid]);
if (is_permutations)
cimg::swap(permutations[indm],permutations[mid]);
16423 if ((*
this)[mid]<(*
this)[indM]) {
16424 cimg::swap((*
this)[indM],(*
this)[mid]);
if (is_permutations)
cimg::swap(permutations[indM],permutations[mid]);
16426 if ((*
this)[indm]<(*
this)[mid]) {
16427 cimg::swap((*
this)[indm],(*
this)[mid]);
if (is_permutations)
cimg::swap(permutations[indm],permutations[mid]);
16430 if (indM - indm>=3) {
16431 const T pivot = (*this)[mid];
16432 int i = indm, j = indM;
16433 if (is_increasing) {
16435 while ((*
this)[i]<pivot) ++i;
16436 while ((*
this)[j]>pivot) --j;
16438 if (is_permutations)
cimg::swap(permutations[i],permutations[j]);
16444 while ((*
this)[i]>pivot) ++i;
16445 while ((*
this)[j]<pivot) --j;
16447 if (is_permutations)
cimg::swap(permutations[i],permutations[j]);
16452 if (indm<j) _quicksort(indm,j,permutations,is_increasing,is_permutations);
16453 if (i<indM) _quicksort(i,indM,permutations,is_increasing,is_permutations);
16476 template<
typename t>
16478 const unsigned int max_iteration=40,
const float lambda=0)
const {
16479 if (
is_empty()) { U.assign(); S.assign(); V.assign(); }
16483 const unsigned int delta =
cimg::min(U._width,U._height);
16484 for (
unsigned int i = 0; i<delta; ++i) U(i,i) = (t)(U(i,i) + lambda);
16486 if (S.size()<_width) S.assign(1,_width);
16487 if (V._width<_width || V._height<_height) V.assign(_width,_width);
16489 t anorm = 0, c, f, g = 0, h, s, scale = 0;
16493 l = i+1; rv1[i] = scale*g; g = s = scale = 0;
16497 for (
int k = i; k<
height(); ++k) { U(i,k)/=scale; s+= U(i,k)*U(i,k); }
16498 f = U(i,i); g = (t)((f>=0?-1:1)*std::sqrt(s)); h=f*g-s; U(i,i) = f-g;
16499 for (
int j = l; j<
width(); ++j) {
16501 for (
int k=i; k<
height(); ++k) s+= U(i,k)*U(j,k);
16503 for (
int k = i; k<
height(); ++k) U(j,k)+= f*U(i,k);
16505 for (
int k = i; k<
height(); ++k) U(i,k)*= scale;
16514 for (
int k = l; k<
width(); ++k) { U(k,i)/= scale; s+= U(k,i)*U(k,i); }
16515 f = U(l,i); g = (t)((f>=0?-1:1)*std::sqrt(s)); h = f*g-s; U(l,i) = f-g;
16516 for (
int k = l; k<
width(); ++k) rv1[k]=U(k,i)/h;
16517 for (
int j = l; j<
height(); ++j) {
16519 for (
int k = l; k<
width(); ++k) s+= U(k,j)*U(k,i);
16520 for (
int k = l; k<
width(); ++k) U(k,j)+= s*rv1[k];
16522 for (
int k = l; k<
width(); ++k) U(k,i)*= scale;
16528 for (
int i =
width()-1; i>=0; --i) {
16531 for (
int j = l; j<
width(); ++j) V(i,j) =(U(j,i)/U(l,i))/g;
16532 for (
int j = l; j<
width(); ++j) {
16534 for (
int k = l; k<
width(); ++k) s+= U(k,i)*V(j,k);
16535 for (
int k = l; k<
width(); ++k) V(j,k)+= s*V(i,k);
16538 for (
int j = l; j<
width(); ++j) V(j,i) = V(i,j) = (t)0.0;
16540 V(i,i) = (t)1.0; g = rv1[i]; l = i;
16545 for (
int j = l; j<
width(); ++j) U(j,i) = 0;
16548 for (
int j = l; j<
width(); ++j) {
16549 s = 0;
for (
int k = l; k<
height(); ++k) s+= U(i,k)*U(j,k);
16551 for (
int k = i; k<
height(); ++k) U(j,k)+= f*U(i,k);
16553 for (
int j = i; j<
height(); ++j) U(i,j)*= g;
16554 }
else for (
int j = i; j<
height(); ++j) U(i,j) = 0;
16558 for (
int k =
width()-1; k>=0; --k) {
16559 for (
unsigned int its = 0; its<max_iteration; ++its) {
16561 for (l = k; l>=1; --l) {
16563 if ((
cimg::abs(rv1[l])+anorm)==anorm) { flag =
false;
break; }
16564 if ((
cimg::abs(S[nm])+anorm)==anorm)
break;
16568 for (
int i = l; i<=k; ++i) {
16569 f = s*rv1[i]; rv1[i] = c*rv1[i];
16570 if ((
cimg::abs(f)+anorm)==anorm)
break;
16571 g = S[i]; h = (t)cimg::_pythagore(f,g); S[i] = h; h = 1/h; c = g*h; s = -f*h;
16572 cimg_forY(U,j) {
const t y = U(nm,j), z = U(i,j); U(nm,j) = y*c + z*s; U(i,j) = z*c - y*s; }
16576 if (l==k) {
if (z<0) { S[k] = -z; cimg_forX(U,j) V(k,j) = -V(k,j); }
break; }
16578 t x = S[l], y = S[nm];
16579 g = rv1[nm]; h = rv1[k];
16580 f = ((y-z)*(y+z)+(g-h)*(g+h))/(2*h*y);
16581 g = (t)cimg::_pythagore(f,1.0);
16582 f = ((x-z)*(x+z)+h*((y/(f+ (f>=0?g:-g)))-h))/x;
16584 for (
int j = l; j<=nm; ++j) {
16586 g = rv1[i]; h = s*g; g = c*g;
16588 t z = (t)cimg::_pythagore(f,h);
16589 rv1[j] = z; c = f/z; s = h/z;
16590 f = x*c+g*s; g = g*c-x*s; h = y*s; y*=c;
16591 cimg_forX(U,jj) {
const t x = V(j,jj), z = V(i,jj); V(j,jj) = x*c + z*s; V(i,jj) = z*c - x*s; }
16592 z = (t)cimg::_pythagore(f,h); S[j] = z;
16593 if (z) { z = 1/z; c = f*z; s = h*z; }
16594 f = c*g+s*y; x = c*y-s*g;
16595 cimg_forY(U,jj) {
const t y = U(j,jj); z = U(i,jj); U(j,jj) = y*c + z*s; U(i,jj) = z*c - y*s; }
16597 rv1[l] = 0; rv1[k]=f; S[k]=x;
16604 S.sort(permutations,
false);
16606 cimg_forY(permutations,y) tmp(y) = U(permutations(y),k);
16607 std::memcpy(U.data(0,k),tmp._data,
sizeof(t)*_width);
16610 cimg_forY(permutations,y) tmp(y) = V(permutations(y),k);
16611 std::memcpy(V.data(0,k),tmp._data,
sizeof(t)*_width);
16623 const unsigned int max_iteration=40,
const float lambda=0)
const {
16625 SVD(res[0],res[1],res[2],sorting,max_iteration,lambda);
16630 template<
typename t>
16632 const int N =
width();
16637 cimg_forX(*
this,i) {
16639 cimg_forX(*
this,j) {
16640 const Tfloat tmp =
cimg::abs((*
this)(j,i));
16641 if (tmp>vmax) vmax = tmp;
16643 if (vmax==0) { indx.fill(0);
return fill(0); }
16646 cimg_forX(*
this,j) {
16647 for (
int i = 0; i<j; ++i) {
16648 Tfloat sum=(*this)(j,i);
16649 for (
int k = 0; k<i; ++k) sum-=(*
this)(k,i)*(*
this)(j,k);
16650 (*this)(j,i) = (T)sum;
16653 for (
int i = j; i<
width(); ++i) {
16654 Tfloat sum=(*this)(j,i);
16655 for (
int k = 0; k<j; ++k) sum-=(*
this)(k,i)*(*
this)(j,k);
16656 (*this)(j,i) = (T)sum;
16657 const Tfloat tmp = vv[i]*cimg::
abs(sum);
16658 if (tmp>=vmax) { vmax=tmp; imax=i; }
16661 cimg_forX(*
this,k) cimg::
swap((*this)(k,imax),(*this)(k,j));
16666 if ((*this)(j,j)==0) (*this)(j,j) = (T)1e-20;
16668 const Tfloat tmp = 1/(Tfloat)(*
this)(j,j);
16669 for (
int i=j+1; i<N; ++i) (*
this)(j,i) = (T)((*this)(j,i)*tmp);
16684 template<
typename tf,
typename t>
16686 const unsigned int starting_node,
const unsigned int ending_node,
16688 if (starting_node>=nb_nodes)
16689 throw CImgArgumentException(
"CImg<%s>::dijkstra(): Specified indice of starting node %u is higher than number of nodes %u.",
16692 dist(starting_node) = 0;
16693 previous_node.assign(1,nb_nodes,1,1,(t)-1);
16694 previous_node(starting_node) = (t)starting_node;
16696 cimg_forX(Q,u) Q(u) = u;
16698 unsigned int sizeQ = nb_nodes;
16701 const unsigned int umin = Q(0);
16702 if (umin==ending_node) sizeQ = 0;
16704 const T dmin = dist(umin);
16706 for (
unsigned int q = 1; q<sizeQ; ++q) {
16707 const unsigned int v = Q(q);
16710 const T alt = dmin + d;
16713 previous_node(v) = (t)umin;
16714 const T distpos = dist(Q(q));
16715 for (
unsigned int pos = q, par = 0; pos && distpos<dist(Q(par=(pos+1)/2-1)); pos=par)
cimg::swap(Q(pos),Q(par));
16721 const T distpos = dist(Q(0));
16722 for (
unsigned int pos = 0, left = 0, right = 0;
16723 ((right=2*(pos+1),(left=right-1))<sizeQ && distpos>dist(Q(left))) || (right<sizeQ && distpos>dist(Q(right)));) {
16725 if (dist(Q(left))<dist(Q(right))) {
cimg::swap(Q(pos),Q(left)); pos = left; }
16726 else {
cimg::swap(Q(pos),Q(right)); pos = right; }
16727 }
else {
cimg::swap(Q(pos),Q(left)); pos = left; }
16735 template<
typename tf,
typename t>
16737 const unsigned int starting_node,
const unsigned int ending_node=~0U) {
16739 return dijkstra(distance,nb_nodes,starting_node,ending_node,foo);
16750 template<
typename t>
16752 return get_dijkstra(starting_node,ending_node,previous_node).move_to(*
this);
16756 template<
typename t>
16758 if (_width!=_height || _depth!=1 || _spectrum!=1)
16760 "dijkstra(): Instance is not a graph adjacency matrix.",
16763 return dijkstra(*
this,_width,starting_node,ending_node,previous_node);
16768 return get_dijkstra(starting_node,ending_node).move_to(*
this);
16784 return CImg<T>(str,std::strlen(str)+(is_last_zero?1:0));
16803 _cimg_static
CImg<T> r(1,2); T *ptr = r._data;
16804 *(ptr++) = a0; *(ptr++) = a1;
16815 _cimg_static
CImg<T> r(1,3); T *ptr = r._data;
16816 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2;
16828 _cimg_static
CImg<T> r(1,4); T *ptr = r._data;
16829 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3;
16834 static CImg<T> vector(
const T& a0,
const T& a1,
const T& a2,
const T& a3,
const T& a4) {
16835 _cimg_static
CImg<T> r(1,5); T *ptr = r._data;
16836 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4;
16841 static CImg<T> vector(
const T& a0,
const T& a1,
const T& a2,
const T& a3,
const T& a4,
const T& a5) {
16842 _cimg_static
CImg<T> r(1,6); T *ptr = r._data;
16843 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5;
16849 const T& a4,
const T& a5,
const T& a6) {
16850 _cimg_static
CImg<T> r(1,7); T *ptr = r._data;
16851 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3;
16852 *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6;
16858 const T& a4,
const T& a5,
const T& a6,
const T& a7) {
16859 _cimg_static
CImg<T> r(1,8); T *ptr = r._data;
16860 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3;
16861 *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7;
16867 const T& a4,
const T& a5,
const T& a6,
const T& a7,
16869 _cimg_static
CImg<T> r(1,9); T *ptr = r._data;
16870 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3;
16871 *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7;
16878 const T& a4,
const T& a5,
const T& a6,
const T& a7,
16879 const T& a8,
const T& a9) {
16880 _cimg_static
CImg<T> r(1,10); T *ptr = r._data;
16881 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3;
16882 *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7;
16883 *(ptr++) = a8; *(ptr++) = a9;
16889 const T& a4,
const T& a5,
const T& a6,
const T& a7,
16890 const T& a8,
const T& a9,
const T& a10) {
16891 _cimg_static
CImg<T> r(1,11); T *ptr = r._data;
16892 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3;
16893 *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7;
16894 *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10;
16900 const T& a4,
const T& a5,
const T& a6,
const T& a7,
16901 const T& a8,
const T& a9,
const T& a10,
const T& a11) {
16902 _cimg_static
CImg<T> r(1,12); T *ptr = r._data;
16903 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3;
16904 *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7;
16905 *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; *(ptr++) = a11;
16911 const T& a4,
const T& a5,
const T& a6,
const T& a7,
16912 const T& a8,
const T& a9,
const T& a10,
const T& a11,
16914 _cimg_static
CImg<T> r(1,13); T *ptr = r._data;
16915 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3;
16916 *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7;
16917 *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; *(ptr++) = a11;
16924 const T& a4,
const T& a5,
const T& a6,
const T& a7,
16925 const T& a8,
const T& a9,
const T& a10,
const T& a11,
16926 const T& a12,
const T& a13) {
16927 _cimg_static
CImg<T> r(1,14); T *ptr = r._data;
16928 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3;
16929 *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7;
16930 *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; *(ptr++) = a11;
16931 *(ptr++) = a12; *(ptr++) = a13;
16937 const T& a4,
const T& a5,
const T& a6,
const T& a7,
16938 const T& a8,
const T& a9,
const T& a10,
const T& a11,
16939 const T& a12,
const T& a13,
const T& a14) {
16940 _cimg_static
CImg<T> r(1,15); T *ptr = r._data;
16941 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3;
16942 *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7;
16943 *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; *(ptr++) = a11;
16944 *(ptr++) = a12; *(ptr++) = a13; *(ptr++) = a14;
16950 const T& a4,
const T& a5,
const T& a6,
const T& a7,
16951 const T& a8,
const T& a9,
const T& a10,
const T& a11,
16952 const T& a12,
const T& a13,
const T& a14,
const T& a15) {
16953 _cimg_static
CImg<T> r(1,16); T *ptr = r._data;
16954 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3;
16955 *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7;
16956 *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; *(ptr++) = a11;
16957 *(ptr++) = a12; *(ptr++) = a13; *(ptr++) = a14; *(ptr++) = a15;
16978 const T& a2,
const T& a3) {
16979 _cimg_static
CImg<T> r(2,2); T *ptr = r._data;
16980 *(ptr++) = a0; *(ptr++) = a1;
16981 *(ptr++) = a2; *(ptr++) = a3;
16998 const T& a3,
const T& a4,
const T& a5,
16999 const T& a6,
const T& a7,
const T& a8) {
17000 _cimg_static
CImg<T> r(3,3); T *ptr = r._data;
17001 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2;
17002 *(ptr++) = a3; *(ptr++) = a4; *(ptr++) = a5;
17003 *(ptr++) = a6; *(ptr++) = a7; *(ptr++) = a8;
17009 const T& a4,
const T& a5,
const T& a6,
const T& a7,
17010 const T& a8,
const T& a9,
const T& a10,
const T& a11,
17011 const T& a12,
const T& a13,
const T& a14,
const T& a15) {
17012 _cimg_static
CImg<T> r(4,4); T *ptr = r._data;
17013 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3;
17014 *(ptr++) = a4; *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7;
17015 *(ptr++) = a8; *(ptr++) = a9; *(ptr++) = a10; *(ptr++) = a11;
17016 *(ptr++) = a12; *(ptr++) = a13; *(ptr++) = a14; *(ptr++) = a15;
17021 static CImg<T> matrix(
const T& a0,
const T& a1,
const T& a2,
const T& a3,
const T& a4,
17022 const T& a5,
const T& a6,
const T& a7,
const T& a8,
const T& a9,
17023 const T& a10,
const T& a11,
const T& a12,
const T& a13,
const T& a14,
17024 const T& a15,
const T& a16,
const T& a17,
const T& a18,
const T& a19,
17025 const T& a20,
const T& a21,
const T& a22,
const T& a23,
const T& a24) {
17026 _cimg_static
CImg<T> r(5,5); T *ptr = r._data;
17027 *(ptr++) = a0; *(ptr++) = a1; *(ptr++) = a2; *(ptr++) = a3; *(ptr++) = a4;
17028 *(ptr++) = a5; *(ptr++) = a6; *(ptr++) = a7; *(ptr++) = a8; *(ptr++) = a9;
17029 *(ptr++) = a10; *(ptr++) = a11; *(ptr++) = a12; *(ptr++) = a13; *(ptr++) = a14;
17030 *(ptr++) = a15; *(ptr++) = a16; *(ptr++) = a17; *(ptr++) = a18; *(ptr++) = a19;
17031 *(ptr++) = a20; *(ptr++) = a21; *(ptr++) = a22; *(ptr++) = a23; *(ptr++) = a24;
17046 return matrix(a0,a1,a1,a2);
17050 static CImg<T> tensor(
const T& a0,
const T& a1,
const T& a2,
const T& a3,
const T& a4,
const T& a5) {
17051 return matrix(a0,a1,a2,a1,a3,a4,a2,a4,a5);
17061 return matrix(a0,0,0,a1);
17066 return matrix(a0,0,0,0,a1,0,0,0,a2);
17071 return matrix(a0,0,0,0,0,a1,0,0,0,0,a2,0,0,0,0,a3);
17076 return matrix(a0,0,0,0,0,0,a1,0,0,0,0,0,a2,0,0,0,0,0,a3,0,0,0,0,0,a4);
17085 cimg_forX(res,x) res(x,x) = 1;
17110 if (!is_quaternion) {
17111 const float norm = (float)std::sqrt(x*x + y*y + z*z),
17112 nx = norm>0?x/norm:0,
17113 ny = norm>0?y/norm:0,
17114 nz = norm>0?z/norm:1,
17116 sina = (float)std::sin(nw/2),
17117 cosa = (float)std::cos(nw/2);
17123 const float norm = (float)std::sqrt(x*x + y*y + z*z + w*w);
17125 else { X = Y = Z = 0; W = 1; }
17127 const float xx = X*X, xy = X*Y, xz = X*Z, xw = X*W, yy = Y*Y, yz = Y*Z, yw = Y*W, zz = Z*Z, zw = Z*W;
17128 return CImg<T>::matrix((T)(1-2*(yy+zz)), (T)(2*(xy+zw)), (T)(2*(xz-yw)),
17129 (T)(2*(xy-zw)), (T)(1-2*(xx+zz)), (T)(2*(yz+xw)),
17130 (T)(2*(xz+yw)), (T)(2*(yz-xw)), (T)(1-2*(xx+yy)));
17146 if (val &&
sizeof(T)!=1) cimg_for(*
this,ptrd,T) *ptrd = val;
17147 else std::memset(_data,(
int)val,
sizeof(T)*
size());
17153 return CImg<T>(_width,_height,_depth,_spectrum).
fill(val);
17163 T *ptrd, *ptre =
end()-1;
17164 for (ptrd = _data; ptrd<ptre; ) { *(ptrd++) = val0; *(ptrd++) = val1; }
17165 if (ptrd!=ptre+1) *(ptrd++) = val0;
17171 return CImg<T>(_width,_height,_depth,_spectrum).
fill(val0,val1);
17177 T *ptrd, *ptre =
end()-2;
17178 for (ptrd = _data; ptrd<ptre; ) { *(ptrd++) = val0; *(ptrd++) = val1; *(ptrd++) = val2; }
17180 switch (ptre - ptrd) {
17181 case 2 : *(--ptre) = val1;
17182 case 1 : *(--ptre) = val0;
17189 return CImg<T>(_width,_height,_depth,_spectrum).
fill(val0,val1,val2);
17195 T *ptrd, *ptre =
end()-3;
17196 for (ptrd = _data; ptrd<ptre; ) { *(ptrd++) = val0; *(ptrd++) = val1; *(ptrd++) = val2; *(ptrd++) = val3; }
17198 switch (ptre - ptrd) {
17199 case 3 : *(--ptre) = val2;
17200 case 2 : *(--ptre) = val1;
17201 case 1 : *(--ptre) = val0;
17208 return CImg<T>(_width,_height,_depth,_spectrum).
fill(val0,val1,val2,val3);
17212 CImg<T>&
fill(
const T val0,
const T val1,
const T val2,
const T val3,
const T val4) {
17214 T *ptrd, *ptre =
end()-4;
17215 for (ptrd = _data; ptrd<ptre; ) { *(ptrd++) = val0; *(ptrd++) = val1; *(ptrd++) = val2; *(ptrd++) = val3; *(ptrd++) = val4; }
17217 switch (ptre - ptrd) {
17218 case 4 : *(--ptre) = val3;
17219 case 3 : *(--ptre) = val2;
17220 case 2 : *(--ptre) = val1;
17221 case 1 : *(--ptre) = val0;
17227 CImg<T> get_fill(
const T val0,
const T val1,
const T val2,
const T val3,
const T val4)
const {
17228 return CImg<T>(_width,_height,_depth,_spectrum).
fill(val0,val1,val2,val3,val4);
17232 CImg<T>&
fill(
const T val0,
const T val1,
const T val2,
const T val3,
const T val4,
const T val5) {
17234 T *ptrd, *ptre =
end()-5;
17235 for (ptrd = _data; ptrd<ptre; ) {
17236 *(ptrd++) = val0; *(ptrd++) = val1; *(ptrd++) = val2; *(ptrd++) = val3; *(ptrd++) = val4; *(ptrd++) = val5;
17239 switch (ptre - ptrd) {
17240 case 5 : *(--ptre) = val4;
17241 case 4 : *(--ptre) = val3;
17242 case 3 : *(--ptre) = val2;
17243 case 2 : *(--ptre) = val1;
17244 case 1 : *(--ptre) = val0;
17250 CImg<T> get_fill(
const T val0,
const T val1,
const T val2,
const T val3,
const T val4,
const T val5)
const {
17251 return CImg<T>(_width,_height,_depth,_spectrum).
fill(val0,val1,val2,val3,val4,val5);
17255 CImg<T>&
fill(
const T val0,
const T val1,
const T val2,
const T val3,
const T val4,
const T val5,
const T val6) {
17257 T *ptrd, *ptre =
end()-6;
17258 for (ptrd = _data; ptrd<ptre; ) {
17259 *(ptrd++) = val0; *(ptrd++) = val1; *(ptrd++) = val2; *(ptrd++) = val3; *(ptrd++) = val4; *(ptrd++) = val5; *(ptrd++) = val6;
17262 switch (ptre - ptrd) {
17263 case 6 : *(--ptre) = val5;
17264 case 5 : *(--ptre) = val4;
17265 case 4 : *(--ptre) = val3;
17266 case 3 : *(--ptre) = val2;
17267 case 2 : *(--ptre) = val1;
17268 case 1 : *(--ptre) = val0;
17274 CImg<T> get_fill(
const T val0,
const T val1,
const T val2,
const T val3,
const T val4,
const T val5,
const T val6)
const {
17275 return CImg<T>(_width,_height,_depth,_spectrum).
fill(val0,val1,val2,val3,val4,val5,val6);
17279 CImg<T>&
fill(
const T val0,
const T val1,
const T val2,
const T val3,
const T val4,
const T val5,
const T val6,
17282 T *ptrd, *ptre =
end()-7;
17283 for (ptrd = _data; ptrd<ptre; ) {
17284 *(ptrd++) = val0; *(ptrd++) = val1; *(ptrd++) = val2; *(ptrd++) = val3;
17285 *(ptrd++) = val4; *(ptrd++) = val5; *(ptrd++) = val6; *(ptrd++) = val7;
17288 switch (ptre - ptrd) {
17289 case 7 : *(--ptre) = val6;
17290 case 6 : *(--ptre) = val5;
17291 case 5 : *(--ptre) = val4;
17292 case 4 : *(--ptre) = val3;
17293 case 3 : *(--ptre) = val2;
17294 case 2 : *(--ptre) = val1;
17295 case 1 : *(--ptre) = val0;
17301 CImg<T> get_fill(
const T val0,
const T val1,
const T val2,
const T val3,
const T val4,
const T val5,
const T val6,
17302 const T val7)
const {
17303 return CImg<T>(_width,_height,_depth,_spectrum).
fill(val0,val1,val2,val3,val4,val5,val6,val7);
17307 CImg<T>&
fill(
const T val0,
const T val1,
const T val2,
const T val3,
const T val4,
const T val5,
const T val6,
17308 const T val7,
const T val8) {
17310 T *ptrd, *ptre =
end()-8;
17311 for (ptrd = _data; ptrd<ptre; ) {
17312 *(ptrd++) = val0; *(ptrd++) = val1; *(ptrd++) = val2;
17313 *(ptrd++) = val3; *(ptrd++) = val4; *(ptrd++) = val5;
17314 *(ptrd++) = val6; *(ptrd++) = val7; *(ptrd++) = val8;
17317 switch (ptre - ptrd) {
17318 case 8 : *(--ptre) = val7;
17319 case 7 : *(--ptre) = val6;
17320 case 6 : *(--ptre) = val5;
17321 case 5 : *(--ptre) = val4;
17322 case 4 : *(--ptre) = val3;
17323 case 3 : *(--ptre) = val2;
17324 case 2 : *(--ptre) = val1;
17325 case 1 : *(--ptre) = val0;
17331 CImg<T> get_fill(
const T val0,
const T val1,
const T val2,
const T val3,
const T val4,
const T val5,
const T val6,
17332 const T val7,
const T val8)
const {
17333 return CImg<T>(_width,_height,_depth,_spectrum).
fill(val0,val1,val2,val3,val4,val5,val6,val7,val8);
17337 CImg<T>&
fill(
const T val0,
const T val1,
const T val2,
const T val3,
const T val4,
const T val5,
const T val6,
17338 const T val7,
const T val8,
const T val9) {
17340 T *ptrd, *ptre =
end()-9;
17341 for (ptrd = _data; ptrd<ptre; ) {
17342 *(ptrd++) = val0; *(ptrd++) = val1; *(ptrd++) = val2; *(ptrd++) = val3; *(ptrd++) = val4;
17343 *(ptrd++) = val5; *(ptrd++) = val6; *(ptrd++) = val7; *(ptrd++) = val8; *(ptrd++) = val9;
17346 switch (ptre - ptrd) {
17347 case 9 : *(--ptre) = val8;
17348 case 8 : *(--ptre) = val7;
17349 case 7 : *(--ptre) = val6;
17350 case 6 : *(--ptre) = val5;
17351 case 5 : *(--ptre) = val4;
17352 case 4 : *(--ptre) = val3;
17353 case 3 : *(--ptre) = val2;
17354 case 2 : *(--ptre) = val1;
17355 case 1 : *(--ptre) = val0;
17361 CImg<T> get_fill(
const T val0,
const T val1,
const T val2,
const T val3,
const T val4,
const T val5,
const T val6,
17362 const T val7,
const T val8,
const T val9)
const {
17363 return CImg<T>(_width,_height,_depth,_spectrum).
fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9);
17367 CImg<T>&
fill(
const T val0,
const T val1,
const T val2,
const T val3,
const T val4,
const T val5,
const T val6,
17368 const T val7,
const T val8,
const T val9,
const T val10) {
17370 T *ptrd, *ptre =
end()-10;
17371 for (ptrd = _data; ptrd<ptre; ) {
17372 *(ptrd++) = val0; *(ptrd++) = val1; *(ptrd++) = val2; *(ptrd++) = val3; *(ptrd++) = val4;
17373 *(ptrd++) = val5; *(ptrd++) = val6; *(ptrd++) = val7; *(ptrd++) = val8; *(ptrd++) = val9;
17377 switch (ptre - ptrd) {
17378 case 10 : *(--ptre) = val9;
17379 case 9 : *(--ptre) = val8;
17380 case 8 : *(--ptre) = val7;
17381 case 7 : *(--ptre) = val6;
17382 case 6 : *(--ptre) = val5;
17383 case 5 : *(--ptre) = val4;
17384 case 4 : *(--ptre) = val3;
17385 case 3 : *(--ptre) = val2;
17386 case 2 : *(--ptre) = val1;
17387 case 1 : *(--ptre) = val0;
17393 CImg<T> get_fill(
const T val0,
const T val1,
const T val2,
const T val3,
const T val4,
const T val5,
const T val6,
17394 const T val7,
const T val8,
const T val9,
const T val10)
const {
17395 return CImg<T>(_width,_height,_depth,_spectrum).
fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10);
17399 CImg<T>&
fill(
const T val0,
const T val1,
const T val2,
const T val3,
const T val4,
const T val5,
const T val6,
17400 const T val7,
const T val8,
const T val9,
const T val10,
const T val11) {
17402 T *ptrd, *ptre =
end()-11;
17403 for (ptrd = _data; ptrd<ptre; ) {
17404 *(ptrd++) = val0; *(ptrd++) = val1; *(ptrd++) = val2; *(ptrd++) = val3; *(ptrd++) = val4; *(ptrd++) = val5;
17405 *(ptrd++) = val6; *(ptrd++) = val7; *(ptrd++) = val8; *(ptrd++) = val9; *(ptrd++) = val10; *(ptrd++) = val11;
17408 switch (ptre - ptrd) {
17409 case 11 : *(--ptre) = val10;
17410 case 10 : *(--ptre) = val9;
17411 case 9 : *(--ptre) = val8;
17412 case 8 : *(--ptre) = val7;
17413 case 7 : *(--ptre) = val6;
17414 case 6 : *(--ptre) = val5;
17415 case 5 : *(--ptre) = val4;
17416 case 4 : *(--ptre) = val3;
17417 case 3 : *(--ptre) = val2;
17418 case 2 : *(--ptre) = val1;
17419 case 1 : *(--ptre) = val0;
17425 CImg<T> get_fill(
const T val0,
const T val1,
const T val2,
const T val3,
const T val4,
const T val5,
const T val6,
17426 const T val7,
const T val8,
const T val9,
const T val10,
const T val11)
const {
17427 return CImg<T>(_width,_height,_depth,_spectrum).
fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11);
17431 CImg<T>&
fill(
const T val0,
const T val1,
const T val2,
const T val3,
const T val4,
const T val5,
const T val6,
17432 const T val7,
const T val8,
const T val9,
const T val10,
const T val11,
const T val12) {
17434 T *ptrd, *ptre =
end()-12;
17435 for (ptrd = _data; ptrd<ptre; ) {
17436 *(ptrd++) = val0; *(ptrd++) = val1; *(ptrd++) = val2; *(ptrd++) = val3; *(ptrd++) = val4; *(ptrd++) = val5;
17437 *(ptrd++) = val6; *(ptrd++) = val7; *(ptrd++) = val8; *(ptrd++) = val9; *(ptrd++) = val10; *(ptrd++) = val11;
17441 switch (ptre - ptrd) {
17442 case 12 : *(--ptre) = val11;
17443 case 11 : *(--ptre) = val10;
17444 case 10 : *(--ptre) = val9;
17445 case 9 : *(--ptre) = val8;
17446 case 8 : *(--ptre) = val7;
17447 case 7 : *(--ptre) = val6;
17448 case 6 : *(--ptre) = val5;
17449 case 5 : *(--ptre) = val4;
17450 case 4 : *(--ptre) = val3;
17451 case 3 : *(--ptre) = val2;
17452 case 2 : *(--ptre) = val1;
17453 case 1 : *(--ptre) = val0;
17459 CImg<T> get_fill(
const T val0,
const T val1,
const T val2,
const T val3,
const T val4,
const T val5,
const T val6,
17460 const T val7,
const T val8,
const T val9,
const T val10,
const T val11,
const T val12)
const {
17461 return CImg<T>(_width,_height,_depth,_spectrum).
fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11,val12);
17465 CImg<T>&
fill(
const T val0,
const T val1,
const T val2,
const T val3,
const T val4,
const T val5,
const T val6,
17466 const T val7,
const T val8,
const T val9,
const T val10,
const T val11,
const T val12,
17469 T *ptrd, *ptre =
end()-13;
17470 for (ptrd = _data; ptrd<ptre; ) {
17471 *(ptrd++) = val0; *(ptrd++) = val1; *(ptrd++) = val2; *(ptrd++) = val3; *(ptrd++) = val4; *(ptrd++) = val5;
17472 *(ptrd++) = val6; *(ptrd++) = val7; *(ptrd++) = val8; *(ptrd++) = val9; *(ptrd++) = val10; *(ptrd++) = val11;
17473 *(ptrd++) = val12; *(ptrd++) = val13;
17476 switch (ptre - ptrd) {
17477 case 13 : *(--ptre) = val12;
17478 case 12 : *(--ptre) = val11;
17479 case 11 : *(--ptre) = val10;
17480 case 10 : *(--ptre) = val9;
17481 case 9 : *(--ptre) = val8;
17482 case 8 : *(--ptre) = val7;
17483 case 7 : *(--ptre) = val6;
17484 case 6 : *(--ptre) = val5;
17485 case 5 : *(--ptre) = val4;
17486 case 4 : *(--ptre) = val3;
17487 case 3 : *(--ptre) = val2;
17488 case 2 : *(--ptre) = val1;
17489 case 1 : *(--ptre) = val0;
17495 CImg<T> get_fill(
const T val0,
const T val1,
const T val2,
const T val3,
const T val4,
const T val5,
const T val6,
17496 const T val7,
const T val8,
const T val9,
const T val10,
const T val11,
const T val12,
17497 const T val13)
const {
17498 return CImg<T>(_width,_height,_depth,_spectrum).
fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11,val12,
17503 CImg<T>&
fill(
const T val0,
const T val1,
const T val2,
const T val3,
const T val4,
const T val5,
const T val6,
17504 const T val7,
const T val8,
const T val9,
const T val10,
const T val11,
const T val12,
17505 const T val13,
const T val14) {
17507 T *ptrd, *ptre =
end()-14;
17508 for (ptrd = _data; ptrd<ptre; ) {
17509 *(ptrd++) = val0; *(ptrd++) = val1; *(ptrd++) = val2; *(ptrd++) = val3; *(ptrd++) = val4; *(ptrd++) = val5;
17510 *(ptrd++) = val6; *(ptrd++) = val7; *(ptrd++) = val8; *(ptrd++) = val9; *(ptrd++) = val10; *(ptrd++) = val11;
17511 *(ptrd++) = val12; *(ptrd++) = val13; *(ptrd++) = val14;
17514 switch (ptre - ptrd) {
17515 case 14 : *(--ptre) = val13;
17516 case 13 : *(--ptre) = val12;
17517 case 12 : *(--ptre) = val11;
17518 case 11 : *(--ptre) = val10;
17519 case 10 : *(--ptre) = val9;
17520 case 9 : *(--ptre) = val8;
17521 case 8 : *(--ptre) = val7;
17522 case 7 : *(--ptre) = val6;
17523 case 6 : *(--ptre) = val5;
17524 case 5 : *(--ptre) = val4;
17525 case 4 : *(--ptre) = val3;
17526 case 3 : *(--ptre) = val2;
17527 case 2 : *(--ptre) = val1;
17528 case 1 : *(--ptre) = val0;
17534 CImg<T> get_fill(
const T val0,
const T val1,
const T val2,
const T val3,
const T val4,
const T val5,
const T val6,
17535 const T val7,
const T val8,
const T val9,
const T val10,
const T val11,
const T val12,
17536 const T val13,
const T val14)
const {
17537 return CImg<T>(_width,_height,_depth,_spectrum).
fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11,val12,
17542 CImg<T>&
fill(
const T val0,
const T val1,
const T val2,
const T val3,
const T val4,
const T val5,
const T val6,
17543 const T val7,
const T val8,
const T val9,
const T val10,
const T val11,
const T val12,
17544 const T val13,
const T val14,
const T val15) {
17546 T *ptrd, *ptre =
end()-15;
17547 for (ptrd = _data; ptrd<ptre; ) {
17548 *(ptrd++) = val0; *(ptrd++) = val1; *(ptrd++) = val2; *(ptrd++) = val3; *(ptrd++) = val4; *(ptrd++) = val5;
17549 *(ptrd++) = val6; *(ptrd++) = val7; *(ptrd++) = val8; *(ptrd++) = val9; *(ptrd++) = val10; *(ptrd++) = val11;
17550 *(ptrd++) = val12; *(ptrd++) = val13; *(ptrd++) = val14; *(ptrd++) = val15;
17553 switch (ptre - ptrd) {
17554 case 15 : *(--ptre) = val14;
17555 case 14 : *(--ptre) = val13;
17556 case 13 : *(--ptre) = val12;
17557 case 12 : *(--ptre) = val11;
17558 case 11 : *(--ptre) = val10;
17559 case 10 : *(--ptre) = val9;
17560 case 9 : *(--ptre) = val8;
17561 case 8 : *(--ptre) = val7;
17562 case 7 : *(--ptre) = val6;
17563 case 6 : *(--ptre) = val5;
17564 case 5 : *(--ptre) = val4;
17565 case 4 : *(--ptre) = val3;
17566 case 3 : *(--ptre) = val2;
17567 case 2 : *(--ptre) = val1;
17568 case 1 : *(--ptre) = val0;
17574 CImg<T> get_fill(
const T val0,
const T val1,
const T val2,
const T val3,
const T val4,
const T val5,
const T val6,
17575 const T val7,
const T val8,
const T val9,
const T val10,
const T val11,
const T val12,
17576 const T val13,
const T val14,
const T val15)
const {
17577 return CImg<T>(_width,_height,_depth,_spectrum).
fill(val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,val10,val11,val12,
17578 val13,val14,val15);
17587 if (
is_empty() || !expression || !*expression)
return *
this;
17591 const CImg<T> _base = std::strstr(expression,
"i(")?+*
this:
CImg<T>(), &base = _base?_base:*
this;
17592 _cimg_math_parser mp(base,expression,
"fill");
17594 cimg_forXYZC(*
this,x,y,z,c) *(ptrd++) = (T)mp.eval((
double)x,(
double)y,(
double)z,(
double)c);
17596 char item[16384] = { 0 }, sep = 0;
17597 const char *nexpression = expression;
17598 unsigned long nb = 0;
17599 const unsigned long siz =
size();
17601 for (
double val = 0; *nexpression && nb<siz; ++nb) {
17603 const int err = std::sscanf(nexpression,
"%4095[ \n\t0-9.e+-]%c",item,&sep);
17604 if (err>0 && std::sscanf(item,
"%lf",&val)==1) {
17605 nexpression+=std::strlen(item) + (err>1?1:0);
17606 *(ptrd++) = (T)val;
17610 if (nb<siz && (sep || *nexpression))
17612 if (repeat_flag && nb && nb<siz)
for (T *ptrs = _data, *
const ptre = _data + siz; ptrd<ptre; ++ptrs) *(ptrd++) = *ptrs;
17620 return (+*
this).
fill(values,repeat_values);
17628 template<
typename t>
17630 if (
is_empty() || !values)
return *
this;
17631 T *ptrd = _data, *ptre = ptrd +
size();
17632 for (t *ptrs = values._data, *ptrs_end = ptrs + values.size(); ptrs<ptrs_end && ptrd<ptre; ++ptrs) *(ptrd++) = (T)*ptrs;
17633 if (repeat_values && ptrd<ptre)
for (T *ptrs = _data; ptrd<ptre; ++ptrs) *(ptrd++) = *ptrs;
17638 template<
typename t>
17640 return repeat_values?
CImg<T>(_width,_height,_depth,_spectrum).
fill(values,repeat_values):(+*
this).
fill(values,repeat_values);
17650 CImg<T>&
fillX(
const unsigned int y,
const unsigned int z,
const unsigned int c,
const int a0, ...) {
17651 #define _cimg_fill1(x,y,z,c,off,siz,t) { \
17652 va_list ap; va_start(ap,a0); T *ptrd = data(x,y,z,c); *ptrd = (T)a0; \
17653 for (unsigned long k = 1; k<siz; ++k) { ptrd+=off; *ptrd = (T)va_arg(ap,t); } \
17655 if (y<_height && z<_depth && c<_spectrum) _cimg_fill1(0,y,z,c,1,_width,
int);
17660 CImg<T>&
fillX(
const unsigned int y,
const unsigned int z,
const unsigned int c,
const double a0, ...) {
17661 if (y<_height && z<_depth && c<_spectrum) _cimg_fill1(0,y,z,c,1,_width,
double);
17672 CImg<T>&
fillY(
const unsigned int x,
const unsigned int z,
const unsigned int c,
const int a0, ...) {
17673 if (x<_width && z<_depth && c<_spectrum) _cimg_fill1(x,0,z,c,_width,_height,
int);
17678 CImg<T>&
fillY(
const unsigned int x,
const unsigned int z,
const unsigned int c,
const double a0, ...) {
17679 if (x<_width && z<_depth && c<_spectrum) _cimg_fill1(x,0,z,c,_width,_height,
double);
17690 CImg<T>&
fillZ(
const unsigned int x,
const unsigned int y,
const unsigned int c,
const int a0, ...) {
17691 const unsigned long wh = (
unsigned long)_width*_height;
17692 if (x<_width && y<_height && c<_spectrum) _cimg_fill1(x,y,0,c,wh,_depth,
int);
17697 CImg<T>&
fillZ(
const unsigned int x,
const unsigned int y,
const unsigned int c,
const double a0, ...) {
17698 const unsigned long wh = (
unsigned long)_width*_height;
17699 if (x<_width && y<_height && c<_spectrum) _cimg_fill1(x,y,0,c,wh,_depth,
double);
17710 CImg<T>&
fillC(
const unsigned int x,
const unsigned int y,
const unsigned int z,
const int a0, ...) {
17711 const unsigned long whd = (
unsigned long)_width*_height*_depth;
17712 if (x<_width && y<_height && z<_depth) _cimg_fill1(x,y,z,0,whd,_spectrum,
int);
17717 CImg<T>&
fillC(
const unsigned int x,
const unsigned int y,
const unsigned int z,
const double a0, ...) {
17718 const unsigned long whd = (
unsigned long)_width*_height*_depth;
17719 if (x<_width && y<_height && z<_depth) _cimg_fill1(x,y,z,0,whd,_spectrum,
double);
17737 for (
const T *ps = _data, *
const pse =
end(); ps<pse; ++ps)
17738 if (*ps!=value) *(pd++) = *ps;
17739 if (pd==res._data)
return CImg<T>();
17740 return res.resize(1,pd-res._data,1,1,-1);
17749 template<
typename t>
17755 template<
typename t>
17757 if (!values)
return *
this;
17758 if (values.size()==1)
return get_discard(*values);
17761 const t *
const pve = values.end();
17762 for (
const T *ps = _data, *
const pse =
end(); ps<pse; ) {
17764 const t *pv = values._data;
17765 while (_ps<pse && pv<pve) {
if (*(_ps++)!=(T)*pv)
break; ++pv; }
17767 const unsigned int l = _ps - ps;
17768 if (l==1) *(pd++) = *ps;
else { std::memcpy(pd,ps,
sizeof(T)*l); pd+=l; }
17772 if (pd==res._data)
return CImg<T>();
17773 return res.resize(1,pd-res._data,1,1,-1);
17796 const float delta = (float)val_max - (
float)val_min;
17797 cimg_for(*
this,ptrd,T) *ptrd = (T)(val_min +
cimg::rand()*delta);
17803 return (+*
this).
rand(val_min,val_max);
17815 if (y>0) cimg_for(*
this,ptrd,T) *ptrd =
cimg::round(*ptrd,y,rounding_type);
17821 return (+*
this).
round(y,rounding_type);
17842 Tfloat nsigma = (Tfloat)sigma, m = 0, M = 0;
17843 if (nsigma==0 && noise_type!=3)
return *
this;
17844 if (nsigma<0 || noise_type==2) m = (Tfloat)
min_max(M);
17845 if (nsigma<0) nsigma = (Tfloat)(-nsigma*(M-m)/100.0);
17846 switch (noise_type) {
17848 cimg_for(*
this,ptrd,T) {
17849 Tfloat val = (Tfloat)(*ptrd + nsigma*
cimg::grand());
17850 if (val>vmax) val = vmax;
17851 if (val<vmin) val = vmin;
17856 cimg_for(*
this,ptrd,T) {
17857 Tfloat val = (Tfloat)(*ptrd + nsigma*
cimg::crand());
17858 if (val>vmax) val = vmax;
17859 if (val<vmin) val = vmin;
17864 if (nsigma<0) nsigma = -nsigma;
17870 cimg_for(*
this,ptrd,T) *ptrd = (T)
cimg::prand(*ptrd);
17874 const Tfloat sqrt2 = (Tfloat)std::sqrt(2.0);
17875 cimg_for(*
this,ptrd,T) {
17877 val0 = (Tfloat)*ptrd/sqrt2,
17880 Tfloat val = (Tfloat)std::sqrt(re*re + im*im);
17881 if (val>vmax) val = vmax;
17882 if (val<vmin) val = vmin;
17888 "noise(): Invalid specified noise type %d "
17889 "(should be { 0=gaussian | 1=uniform | 2=salt&Pepper | 3=poisson }).",
17899 return (+*
this).
noise(sigma,noise_type);
17915 const T a = min_value<max_value?min_value:max_value, b = min_value<max_value?max_value:min_value;
17917 const Tfloat fm = (Tfloat)m, fM = (Tfloat)M;
17918 if (m==M)
return fill(min_value);
17919 if (m!=a || M!=b) cimg_for(*
this,ptrd,T) *ptrd = (T)((*ptrd-fm)/(fM-fm)*(b-a)+a);
17939 const unsigned long whd = (
unsigned long)_width*_height*_depth;
17940 cimg_forXYZ(*
this,x,y,z) {
17941 const T *ptrs = ptrd;
17943 cimg_forC(*
this,c) { n+=
cimg::sqr((
float)*ptrs); ptrs+=whd; }
17944 n = (float)std::sqrt(n);
17946 if (n>0) cimg_forC(*
this,c) { *_ptrd = (T)(*_ptrd/n); _ptrd+=whd; }
17947 else cimg_forC(*
this,c) { *_ptrd = (T)0; _ptrd+=whd; }
17968 if (_spectrum==1)
return abs();
17969 return get_norm(norm_type).move_to(*
this);
17975 if (_spectrum==1)
return get_abs();
17976 const T *ptrs = _data;
17977 const unsigned long whd = (
unsigned long)_width*_height*_depth;
17979 Tfloat *ptrd = res._data;
17980 switch (norm_type) {
17982 cimg_forXYZ(*
this,x,y,z) {
17984 const T *_ptrs = ptrs++;
17985 cimg_forC(*
this,c) {
const Tfloat val = (Tfloat)
cimg::abs(*_ptrs);
if (val>n) n = val; _ptrs+=whd; }
17990 cimg_forXYZ(*
this,x,y,z) {
17992 const T *_ptrs = ptrs++;
17993 cimg_forC(*
this,c) { n+=
cimg::abs(*_ptrs); _ptrs+=whd; }
17998 cimg_forXYZ(*
this,x,y,z) {
18000 const T *_ptrs = ptrs++;
18001 cimg_forC(*
this,c) { n+=
cimg::sqr((Tfloat)*_ptrs); _ptrs+=whd; }
18002 *(ptrd++) = (Tfloat)std::sqrt((Tfloat)n);
18022 const T a = min_value<max_value?min_value:max_value, b = min_value<max_value?max_value:min_value;
18023 cimg_for(*
this,ptrd,T) *ptrd = (*ptrd<a)?a:((*ptrd>b)?b:*ptrd);
18029 return (+*
this).
cut(min_value,max_value);
18046 "quantize(): Invalid quantization request with 0 values.",
18050 Tfloat m, M = (Tfloat)
max_min(m), range = M - m;
18052 if (keep_range) cimg_for(*
this,ptrd,T) {
18053 const unsigned int val = (
unsigned int)((*ptrd-m)*nb_levels/range);
18054 *ptrd = (T)(m +
cimg::min(val,nb_levels-1)*range/nb_levels);
18055 }
else cimg_for(*
this,ptrd,T) {
18056 const unsigned int val = (
unsigned int)((*ptrd-m)*nb_levels/range);
18065 return (+*
this).
quantize(n,keep_range);
18080 CImg<T>&
threshold(
const T value,
const bool soft_threshold=
false,
const bool strict_threshold=
false) {
18082 if (strict_threshold) {
18083 if (soft_threshold) cimg_for(*
this,ptrd,T) {
const T v = *ptrd; *ptrd = v>value?(T)(v-value):v<-(float)value?(T)(v+value):(T)0; }
18084 else cimg_for(*
this,ptrd,T) *ptrd = *ptrd>value?(T)1:(T)0;
18086 if (soft_threshold) cimg_for(*
this,ptrd,T) {
const T v = *ptrd; *ptrd = v>=value?(T)(v-value):v<=-(float)value?(T)(v+value):(T)0; }
18087 else cimg_for(*
this,ptrd,T) *ptrd = *ptrd>=value?(T)1:(T)0;
18094 return (+*
this).
threshold(value,soft_threshold,strict_threshold);
18121 T vmin = min_value<max_value?min_value:max_value, vmax = min_value<max_value?max_value:min_value;
18122 if (vmin==vmax && vmin==0) vmin =
min_max(vmax);
18124 cimg_for(*
this,ptrs,T) {
18125 const T val = *ptrs;
18126 if (val>=vmin && val<=vmax) ++res[val==vmax?nb_levels-1:(
unsigned int)((val-vmin)*nb_levels/(vmax-vmin))];
18146 CImg<T>&
equalize(
const unsigned int nb_levels,
const T min_value=(T)0,
const T max_value=(T)0) {
18148 T vmin = min_value, vmax = max_value;
18149 if (vmin==vmax && vmin==0) vmin =
min_max(vmax);
18153 cimg_forX(hist,pos) { cumul+=hist[pos]; hist[pos] = cumul; }
18154 cimg_for(*
this,ptrd,T) {
18155 const int pos = (
unsigned int)((*ptrd-vmin)*(nb_levels-1)/(vmax-vmin));
18156 if (pos>=0 && pos<(
int)nb_levels) *ptrd = (T)(vmin + (vmax-vmin)*hist[pos]/
size());
18164 return (+*
this).
equalize(nblevels,val_min,val_max);
18182 template<
typename t>
18184 return get_index(colormap,dithering,map_indexes).move_to(*
this);
18188 template<
typename t>
18191 if (colormap._spectrum!=_spectrum)
18193 "index(): Instance and specified colormap (%u,%u,%u,%u,%p) "
18194 "have incompatible dimensions.",
18196 colormap._width,colormap._height,colormap._depth,colormap._spectrum,colormap._data);
18198 typedef typename CImg<t>::Tuint tuint;
18200 const unsigned long whd = (
unsigned long)_width*_height*_depth, pwhd = (
unsigned long)colormap._width*colormap._height*colormap._depth;
18201 CImg<tuint> res(_width,_height,_depth,map_indexes?_spectrum:1);
18202 tuint *ptrd = res._data;
18204 const float ndithering = (dithering<0?0:dithering>1?1:dithering)/16;
18205 Tfloat valm = 0, valM = (Tfloat)
max_min(valm);
18206 if (valm==valM && valm>=0 && valM<=255) { valm = 0; valM = 255; }
18208 Tfloat *cache_current = cache.data(1,0,0,0), *cache_next = cache.data(1,1,0,0);
18209 const unsigned long cwhd = (
unsigned long)cache._width*cache._height*cache._depth;
18210 switch (_spectrum) {
18212 cimg_forYZ(*
this,y,z) {
18214 Tfloat *ptrc0 = cache_next;
const T *ptrs0 =
data(0,y+1,z,0);
18215 cimg_forX(*
this,x) *(ptrc0++) = (Tfloat)*(ptrs0++);
18217 Tfloat *ptrs0 = cache_current, *ptrsn0 = cache_next;
18218 cimg_forX(*
this,x) {
18219 const Tfloat _val0 = (Tfloat)*ptrs0, val0 = _val0<valm?valm:_val0>valM?valM:_val0;
18221 for (
const t *ptrp0 = colormap._data, *ptrp_end = ptrp0 + pwhd; ptrp0<ptrp_end; ) {
18222 const Tfloat pval0 = (Tfloat)*(ptrp0++) - val0, dist = pval0*pval0;
18223 if (dist<distmin) { ptrmin0 = ptrp0 - 1; distmin = dist; }
18225 const Tfloat err0 = ((*(ptrs0++)=val0) - (Tfloat)*ptrmin0)*ndithering;
18226 *ptrs0+=7*err0; *(ptrsn0-1)+=3*err0; *(ptrsn0++)+=5*err0; *ptrsn0+=err0;
18227 if (map_indexes) *(ptrd++) = (tuint)*ptrmin0;
else *(ptrd++) = (tuint)(ptrmin0 - colormap._data);
18233 tuint *ptrd1 = ptrd + whd;
18234 cimg_forYZ(*
this,y,z) {
18236 Tfloat *ptrc0 = cache_next, *ptrc1 = ptrc0 + cwhd;
18237 const T *ptrs0 =
data(0,y+1,z,0), *ptrs1 = ptrs0 + whd;
18238 cimg_forX(*
this,x) { *(ptrc0++) = (Tfloat)*(ptrs0++); *(ptrc1++) = (Tfloat)*(ptrs1++); }
18241 *ptrs0 = cache_current, *ptrs1 = ptrs0 + cwhd,
18242 *ptrsn0 = cache_next, *ptrsn1 = ptrsn0 + cwhd;
18243 cimg_forX(*
this,x) {
18245 _val0 = (Tfloat)*ptrs0, val0 = _val0<valm?valm:_val0>valM?valM:_val0,
18246 _val1 = (Tfloat)*ptrs1, val1 = _val1<valm?valm:_val1>valM?valM:_val1;
18248 for (
const t *ptrp0 = colormap._data, *ptrp1 = ptrp0 + pwhd, *ptrp_end = ptrp1; ptrp0<ptrp_end; ) {
18250 pval0 = (Tfloat)*(ptrp0++) - val0, pval1 = (Tfloat)*(ptrp1++) - val1,
18251 dist = pval0*pval0 + pval1*pval1;
18252 if (dist<distmin) { ptrmin0 = ptrp0 - 1; distmin = dist; }
18254 const t *
const ptrmin1 = ptrmin0 + pwhd;
18256 err0 = ((*(ptrs0++)=val0) - (Tfloat)*ptrmin0)*ndithering,
18257 err1 = ((*(ptrs1++)=val1) - (Tfloat)*ptrmin1)*ndithering;
18258 *ptrs0+=7*err0; *ptrs1+=7*err1;
18259 *(ptrsn0-1)+=3*err0; *(ptrsn1-1)+=3*err1;
18260 *(ptrsn0++)+=5*err0; *(ptrsn1++)+=5*err1;
18261 *ptrsn0+=err0; *ptrsn1+=err1;
18262 if (map_indexes) { *(ptrd++) = (tuint)*ptrmin0; *(ptrd1++) = (tuint)*ptrmin1; }
18263 else *(ptrd++) = (tuint)(ptrmin0 - colormap._data);
18269 tuint *ptrd1 = ptrd + whd, *ptrd2 = ptrd1 + whd;
18270 cimg_forYZ(*
this,y,z) {
18272 Tfloat *ptrc0 = cache_next, *ptrc1 = ptrc0 + cwhd, *ptrc2 = ptrc1 + cwhd;
18273 const T *ptrs0 =
data(0,y+1,z,0), *ptrs1 = ptrs0 + whd, *ptrs2 = ptrs1 + whd;
18274 cimg_forX(*
this,x) { *(ptrc0++) = (Tfloat)*(ptrs0++); *(ptrc1++) = (Tfloat)*(ptrs1++); *(ptrc2++) = (Tfloat)*(ptrs2++); }
18277 *ptrs0 = cache_current, *ptrs1 = ptrs0 + cwhd, *ptrs2 = ptrs1 + cwhd,
18278 *ptrsn0 = cache_next, *ptrsn1 = ptrsn0 + cwhd, *ptrsn2 = ptrsn1 + cwhd;
18279 cimg_forX(*
this,x) {
18281 _val0 = (Tfloat)*ptrs0, val0 = _val0<valm?valm:_val0>valM?valM:_val0,
18282 _val1 = (Tfloat)*ptrs1, val1 = _val1<valm?valm:_val1>valM?valM:_val1,
18283 _val2 = (Tfloat)*ptrs2, val2 = _val2<valm?valm:_val2>valM?valM:_val2;
18285 for (
const t *ptrp0 = colormap._data, *ptrp1 = ptrp0 + pwhd, *ptrp2 = ptrp1 + pwhd, *ptrp_end = ptrp1; ptrp0<ptrp_end; ) {
18287 pval0 = (Tfloat)*(ptrp0++) - val0, pval1 = (Tfloat)*(ptrp1++) - val1, pval2 = (Tfloat)*(ptrp2++) - val2,
18288 dist = pval0*pval0 + pval1*pval1 + pval2*pval2;
18289 if (dist<distmin) { ptrmin0 = ptrp0 - 1; distmin = dist; }
18291 const t *
const ptrmin1 = ptrmin0 + pwhd, *
const ptrmin2 = ptrmin1 + pwhd;
18293 err0 = ((*(ptrs0++)=val0) - (Tfloat)*ptrmin0)*ndithering,
18294 err1 = ((*(ptrs1++)=val1) - (Tfloat)*ptrmin1)*ndithering,
18295 err2 = ((*(ptrs2++)=val2) - (Tfloat)*ptrmin2)*ndithering;
18297 *ptrs0+=7*err0; *ptrs1+=7*err1; *ptrs2+=7*err2;
18298 *(ptrsn0-1)+=3*err0; *(ptrsn1-1)+=3*err1; *(ptrsn2-1)+=3*err2;
18299 *(ptrsn0++)+=5*err0; *(ptrsn1++)+=5*err1; *(ptrsn2++)+=5*err2;
18300 *ptrsn0+=err0; *ptrsn1+=err1; *ptrsn2+=err2;
18302 if (map_indexes) { *(ptrd++) = (tuint)*ptrmin0; *(ptrd1++) = (tuint)*ptrmin1; *(ptrd2++) = (tuint)*ptrmin2; }
18303 else *(ptrd++) = (tuint)(ptrmin0 - colormap._data);
18309 cimg_forYZ(*
this,y,z) {
18311 Tfloat *ptrc = cache_next;
18312 cimg_forC(*
this,c) {
18313 Tfloat *_ptrc = ptrc;
const T *_ptrs =
data(0,y+1,z,c);
18314 cimg_forX(*
this,x) *(_ptrc++) = (Tfloat)*(_ptrs++);
18318 Tfloat *ptrs = cache_current, *ptrsn = cache_next;
18319 cimg_forX(*
this,x) {
18321 for (
const t *ptrp = colormap._data, *ptrp_end = ptrp + pwhd; ptrp<ptrp_end; ++ptrp) {
18322 Tfloat dist = 0; Tfloat *_ptrs = ptrs;
const t *_ptrp = ptrp;
18323 cimg_forC(*
this,c) {
18324 const Tfloat _val = *_ptrs, val = _val<valm?valm:_val>valM?valM:_val;
18325 dist+=
cimg::sqr((*_ptrs=val) - (Tfloat)*_ptrp); _ptrs+=cwhd; _ptrp+=pwhd;
18327 if (dist<distmin) { ptrmin = ptrp; distmin = dist; }
18329 const t *_ptrmin = ptrmin; Tfloat *_ptrs = ptrs++, *_ptrsn = (ptrsn++)-1;
18330 cimg_forC(*
this,c) {
18331 const Tfloat err = (*(_ptrs++) - (Tfloat)*_ptrmin)*ndithering;
18332 *_ptrs+=7*err; *(_ptrsn++)+=3*err; *(_ptrsn++)+=5*err; *_ptrsn+=err;
18333 _ptrmin+=pwhd; _ptrs+=cwhd-1; _ptrsn+=cwhd-2;
18336 tuint *_ptrd = ptrd++;
18337 cimg_forC(*
this,c) { *_ptrd = (tuint)*ptrmin; _ptrd+=whd; ptrmin+=pwhd; }
18339 else *(ptrd++) = (tuint)(ptrmin - colormap._data);
18345 switch (_spectrum) {
18347 for (
const T *ptrs0 = _data, *ptrs_end = ptrs0 + whd; ptrs0<ptrs_end; ) {
18348 const Tfloat val0 = (Tfloat)*(ptrs0++);
18350 for (
const t *ptrp0 = colormap._data, *ptrp_end = ptrp0 + pwhd; ptrp0<ptrp_end; ) {
18351 const Tfloat pval0 = (Tfloat)*(ptrp0++) - val0, dist = pval0*pval0;
18352 if (dist<distmin) { ptrmin0 = ptrp0 - 1; distmin = dist; }
18354 if (map_indexes) *(ptrd++) = (tuint)*ptrmin0;
else *(ptrd++) = (tuint)(ptrmin0 - colormap._data);
18358 tuint *ptrd1 = ptrd + whd;
18359 for (
const T *ptrs0 = _data, *ptrs1 = ptrs0 + whd, *ptrs_end = ptrs1; ptrs0<ptrs_end; ) {
18360 const Tfloat val0 = (Tfloat)*(ptrs0++), val1 = (Tfloat)*(ptrs1++);
18362 for (
const t *ptrp0 = colormap._data, *ptrp1 = ptrp0 + pwhd, *ptrp_end = ptrp1; ptrp0<ptrp_end; ) {
18364 pval0 = (Tfloat)*(ptrp0++) - val0, pval1 = (Tfloat)*(ptrp1++) - val1,
18365 dist = pval0*pval0 + pval1*pval1;
18366 if (dist<distmin) { ptrmin0 = ptrp0 - 1; distmin = dist; }
18368 if (map_indexes) { *(ptrd++) = (tuint)*ptrmin0; *(ptrd1++) = (tuint)*(ptrmin0 + pwhd); }
18369 else *(ptrd++) = (tuint)(ptrmin0 - colormap._data);
18373 tuint *ptrd1 = ptrd + whd, *ptrd2 = ptrd1 + whd;
18374 for (
const T *ptrs0 = _data, *ptrs1 = ptrs0 + whd, *ptrs2 = ptrs1 + whd, *ptrs_end = ptrs1; ptrs0<ptrs_end; ) {
18375 const Tfloat val0 = (Tfloat)*(ptrs0++), val1 = (Tfloat)*(ptrs1++), val2 = (Tfloat)*(ptrs2++);
18377 for (
const t *ptrp0 = colormap._data, *ptrp1 = ptrp0 + pwhd, *ptrp2 = ptrp1 + pwhd, *ptrp_end = ptrp1; ptrp0<ptrp_end; ) {
18379 pval0 = (Tfloat)*(ptrp0++) - val0, pval1 = (Tfloat)*(ptrp1++) - val1, pval2 = (Tfloat)*(ptrp2++) - val2,
18380 dist = pval0*pval0 + pval1*pval1 + pval2*pval2;
18381 if (dist<distmin) { ptrmin0 = ptrp0 - 1; distmin = dist; }
18383 if (map_indexes) { *(ptrd++) = (tuint)*ptrmin0; *(ptrd1++) = (tuint)*(ptrmin0 + pwhd); *(ptrd2++) = (tuint)*(ptrmin0 + 2*pwhd); }
18384 else *(ptrd++) = (tuint)(ptrmin0 - colormap._data);
18388 for (
const T *ptrs = _data, *ptrs_end = ptrs + whd; ptrs<ptrs_end; ++ptrs) {
18390 for (
const t *ptrp = colormap._data, *ptrp_end = ptrp + pwhd; ptrp<ptrp_end; ++ptrp) {
18391 Tfloat dist = 0;
const T *_ptrs = ptrs;
const t *_ptrp = ptrp;
18392 cimg_forC(*
this,c) { dist+=
cimg::sqr((Tfloat)*_ptrs - (Tfloat)*_ptrp); _ptrs+=whd; _ptrp+=pwhd; }
18393 if (dist<distmin) { ptrmin = ptrp; distmin = dist; }
18396 tuint *_ptrd = ptrd++;
18397 cimg_forC(*
this,c) { *_ptrd = (tuint)*ptrmin; _ptrd+=whd; ptrmin+=pwhd; }
18399 else *(ptrd++) = (tuint)(ptrmin - colormap._data);
18419 template<
typename t>
18421 return get_map(colormap).move_to(*
this);
18425 template<
typename t>
18427 if (_spectrum!=1 && colormap._spectrum!=1)
18429 "map(): Instance and specified colormap (%u,%u,%u,%u,%p) "
18430 "have incompatible dimensions.",
18432 colormap._width,colormap._height,colormap._depth,colormap._spectrum,colormap._data);
18434 const unsigned long whd = (
unsigned long)_width*_height*_depth, pwhd = (
unsigned long)colormap._width*colormap._height*colormap._depth;
18435 CImg<t> res(_width,_height,_depth,colormap._spectrum==1?_spectrum:colormap._spectrum);
18436 switch (colormap._spectrum) {
18438 const T *ptrs = _data;
18439 cimg_for(res,ptrd,t) {
18440 const unsigned long _ind = (
unsigned long)*(ptrs++), ind = _ind<pwhd?_ind:0;
18441 *ptrd = colormap[ind];
18445 const t *
const ptrp0 = colormap._data, *ptrp1 = ptrp0 + pwhd;
18446 t *ptrd0 = res._data, *ptrd1 = ptrd0 + whd;
18447 for (
const T *ptrs = _data, *ptrs_end = ptrs + whd; ptrs<ptrs_end; ) {
18448 const unsigned long _ind = (
unsigned long)*(ptrs++), ind = _ind<pwhd?_ind:0;
18449 *(ptrd0++) = ptrp0[ind]; *(ptrd1++) = ptrp1[ind];
18453 const t *
const ptrp0 = colormap._data, *ptrp1 = ptrp0 + pwhd, *ptrp2 = ptrp1 + pwhd;
18454 t *ptrd0 = res._data, *ptrd1 = ptrd0 + whd, *ptrd2 = ptrd1 + whd;
18455 for (
const T *ptrs = _data, *ptrs_end = ptrs + whd; ptrs<ptrs_end; ) {
18456 const unsigned long _ind = (
unsigned long)*(ptrs++), ind = _ind<pwhd?_ind:0;
18457 *(ptrd0++) = ptrp0[ind]; *(ptrd1++) = ptrp1[ind]; *(ptrd2++) = ptrp2[ind];
18461 t *ptrd = res._data;
18462 for (
const T *ptrs = _data, *ptrs_end = ptrs + whd; ptrs<ptrs_end; ) {
18463 const unsigned long _ind = (
unsigned long)*(ptrs++), ind = _ind<pwhd?_ind:0;
18464 const t *ptrp = colormap._data + ind;
18465 t *_ptrd = ptrd++; cimg_forC(res,c) { *_ptrd = *ptrp; _ptrd+=whd; ptrp+=pwhd; }
18483 CImg<T>&
label(
const bool is_high_connectivity=
false,
const Tfloat tolerance=0) {
18484 return get_label(is_high_connectivity,tolerance).move_to(*
this);
18489 const Tfloat tolerance=0)
const {
18493 int dx[13], dy[13], dz[13], nb = 0;
18494 dx[nb]=1; dy[nb] = 0; dz[nb++]=0;
18495 dx[nb]=0; dy[nb] = 1; dz[nb++]=0;
18496 if (is_high_connectivity) {
18497 dx[nb]=1; dy[nb] = 1; dz[nb++]=0;
18498 dx[nb]=1; dy[nb] = -1; dz[nb++]=0;
18501 dx[nb]=0; dy[nb] = 0; dz[nb++]=1;
18502 if (is_high_connectivity) {
18503 dx[nb]=1; dy[nb] = 1; dz[nb++]=-1;
18504 dx[nb]=1; dy[nb] = 0; dz[nb++]=-1;
18505 dx[nb]=1; dy[nb] = -1; dz[nb++]=-1;
18506 dx[nb]=0; dy[nb] = 1; dz[nb++]=-1;
18508 dx[nb]=0; dy[nb] = 1; dz[nb++]=1;
18509 dx[nb]=1; dy[nb] = -1; dz[nb++]=1;
18510 dx[nb]=1; dy[nb] = 0; dz[nb++]=1;
18511 dx[nb]=1; dy[nb] = 1; dz[nb++]=1;
18514 return _get_label(nb,dx,dy,dz,tolerance);
18522 template<
typename t>
18524 return get_label(connectivity_mask,tolerance).move_to(*
this);
18528 template<
typename t>
18530 const Tfloat tolerance=0)
const {
18532 cimg_for(connectivity_mask,ptr,t)
if (*ptr) ++nb;
18533 CImg<intT> dx(nb,1,1,1,0), dy(nb,1,1,1,0), dz(nb,1,1,1,0);
18535 cimg_forXYZ(connectivity_mask,x,y,z)
if ((x || y || z) &&
18536 connectivity_mask(x,y,z)) {
18537 dx[nb] = x; dy[nb] = y; dz[nb++] = z;
18539 return _get_label(nb,dx,dy,dz,tolerance);
18543 *
const dx,
const int *
const dy,
const int *
const dz,
18544 const Tfloat tolerance)
const {
18546 cimg_forC(*
this,c) {
18550 unsigned long *ptr = _res.data();
18551 cimg_foroff(_res,p) *(ptr++) = p;
18554 for (
unsigned int n = 0; n<nb; ++n) {
18555 const int _dx = dx[n], _dy = dy[n], _dz = dz[n];
18556 if (_dx || _dy || _dz) {
18559 x1 = _dx<0?_width:_width - _dx,
18561 y1 = _dy<0?_height:_height - _dy,
18563 z1 = _dz<0?_depth:_depth - _dz;
18564 const long wh = (long)_width*_height, offset = (
long)_dz*wh + (long)_dy*_width + _dx;
18565 for (
long z = z0, nz = z0 + _dz, pz = z0*wh; z<z1; ++z, ++nz, pz+=wh) {
18566 for (
long y = y0, ny = y0 + _dy, py = y0*_width + pz; y<y1; ++y, ++ny, py+=_width) {
18567 for (
long x = x0, nx = x0 + _dx, p = x0 + py; x<x1; ++x, ++nx, ++p) {
18568 if ((Tfloat)
cimg::abs((*
this)(x,y,z,c,wh)-(*
this)(nx,ny,nz,c,wh))<=tolerance) {
18569 const long q = p +
offset;
18570 unsigned long x, y;
18571 for (x = p<q?q:p, y = p<q?p:q; x!=y && _res[x]!=x; ) { x = _res[x];
if (x<y)
cimg::swap(x,y); }
18572 if (x!=y) _res[x] = y;
18573 for (
unsigned long _p = p; _p!=y; ) {
const unsigned long h = _res[_p]; _res[_p] = y; _p = h; }
18574 for (
unsigned long _q = q; _q!=y; ) {
const unsigned long h = _res[_q]; _res[_q] = y; _q = h; }
18583 unsigned long counter = 0;
18585 cimg_foroff(_res,p) { *ptr = *ptr==p?counter++:_res[*ptr]; ++ptr; }
18605 colormap.assign(1,256,1,3);
18606 for (
unsigned int index = 0, r = 16; r<256; r+=32)
18607 for (
unsigned int g = 16; g<256; g+=32)
18608 for (
unsigned int b = 32; b<256; b+=64) {
18609 colormap(0,
index,0) = (Tuchar)r;
18610 colormap(0,
index,1) = (Tuchar)g;
18611 colormap(0,
index++,2) = (Tuchar)b;
18626 tmp.get_shared_channel(0).sequence(0,359);
18627 colormap = tmp.HSVtoRGB();
18638 static const unsigned char pal[] = {
18639 217,62,88,75,1,237,240,12,56,160,165,116,1,1,204,2,15,248,148,185,133,141,46,246,222,116,16,5,207,226,
18640 17,114,247,1,214,53,238,0,95,55,233,235,109,0,17,54,33,0,90,30,3,0,94,27,19,0,68,212,166,130,0,15,7,119,
18641 238,2,246,198,0,3,16,10,13,2,25,28,12,6,2,99,18,141,30,4,3,140,12,4,30,233,7,10,0,136,35,160,168,184,20,
18642 233,0,1,242,83,90,56,180,44,41,0,6,19,207,5,31,214,4,35,153,180,75,21,76,16,202,218,22,17,2,136,71,74,
18643 81,251,244,148,222,17,0,234,24,0,200,16,239,15,225,102,230,186,58,230,110,12,0,7,129,249,22,241,37,219,
18644 1,3,254,210,3,212,113,131,197,162,123,252,90,96,209,60,0,17,0,180,249,12,112,165,43,27,229,77,40,195,12,
18645 87,1,210,148,47,80,5,9,1,137,2,40,57,205,244,40,8,252,98,0,40,43,206,31,187,0,180,1,69,70,227,131,108,0,
18646 223,94,228,35,248,243,4,16,0,34,24,2,9,35,73,91,12,199,51,1,249,12,103,131,20,224,2,70,32,
18647 233,1,165,3,8,154,246,233,196,5,0,6,183,227,247,195,208,36,0,0,226,160,210,198,69,153,210,1,23,8,192,2,4,
18648 137,1,0,52,2,249,241,129,0,0,234,7,238,71,7,32,15,157,157,252,158,2,250,6,13,30,11,162,0,199,21,11,27,224,
18649 4,157,20,181,111,187,218,3,0,11,158,230,196,34,223,22,248,135,254,210,157,219,0,117,239,3,255,4,227,5,247,
18650 11,4,3,188,111,11,105,195,2,0,14,1,21,219,192,0,183,191,113,241,1,12,17,248,0,48,7,19,1,254,212,0,239,246,
18651 0,23,0,250,165,194,194,17,3,253,0,24,6,0,141,167,221,24,212,2,235,243,0,0,205,1,251,133,204,28,4,6,1,10,
18652 141,21,74,12,236,254,228,19,1,0,214,1,186,13,13,6,13,16,27,209,6,216,11,207,251,59,32,9,155,23,19,235,143,
18653 116,6,213,6,75,159,23,6,0,228,4,10,245,249,1,7,44,234,4,102,174,0,19,239,103,16,15,18,8,214,22,4,47,244,
18654 255,8,0,251,173,1,212,252,250,251,252,6,0,29,29,222,233,246,5,149,0,182,180,13,151,0,203,183,0,35,149,0,
18655 235,246,254,78,9,17,203,73,11,195,0,3,5,44,0,0,237,5,106,6,130,16,214,20,168,247,168,4,207,11,5,1,232,251,
18656 129,210,116,231,217,223,214,27,45,38,4,177,186,249,7,215,172,16,214,27,249,230,236,2,34,216,217,0,175,30,
18657 243,225,244,182,20,212,2,226,21,255,20,0,2,13,62,13,191,14,76,64,20,121,4,118,0,216,1,147,0,2,210,1,215,
18658 95,210,236,225,184,46,0,248,24,11,1,9,141,250,243,9,221,233,160,11,147,2,55,8,23,12,253,9,0,54,0,231,6,3,
18659 141,8,2,246,9,180,5,11,8,227,8,43,110,242,1,130,5,97,36,10,6,219,86,133,11,108,6,1,5,244,67,19,28,0,174,
18660 154,16,127,149,252,188,196,196,228,244,9,249,0,0,0,37,170,32,250,0,73,255,23,3,224,234,38,195,198,0,255,87,
18661 33,221,174,31,3,0,189,228,6,153,14,144,14,108,197,0,9,206,245,254,3,16,253,178,248,0,95,125,8,0,3,168,21,
18662 23,168,19,50,240,244,185,0,1,144,10,168,31,82,1,13 };
18663 static const CImg<Tuchar> colormap(pal,1,256,1,3,
false);
18675 colormap.assign(1,4,1,3,0);
18676 colormap[1] = colormap[2] = colormap[3] = colormap[6] = colormap[7] = colormap[11] = 255;
18677 colormap.resize(1,256,1,3,3);
18689 if (!colormap) colormap.assign(1,2,1,3).fill(0,255,255,0,255,255).resize(1,256,1,3,3);
18701 colormap.assign(1,4,1,3,0);
18702 colormap[2] = colormap[3] = colormap[5] = colormap[6] = colormap[8] = colormap[9] = 255;
18703 colormap.resize(1,256,1,3,3);
18716 colormap.assign(1,4,1,3,0);
18717 colormap[0] = colormap[1] = colormap[5] = colormap[9] = colormap[10] = 255;
18718 colormap.resize(1,256,1,3,0,2);
18731 colormap.assign(1,8,1,3,0);
18732 colormap[1] = colormap[3] = colormap[5] = colormap[7] =
18733 colormap[10] = colormap[11] = colormap[12] = colormap[13] =
18734 colormap[20] = colormap[21] = colormap[22] = colormap[23] = 255;
18735 colormap.resize(1,256,1,3,3);
18742 cimg_for(*
this,ptr,T) {
18744 sval = (Tfloat)*ptr,
18745 nsval = (sval<0?0:sval>255?255:sval)/255,
18746 val = (Tfloat)(nsval<=0.04045f?nsval/12.92f:std::pow((nsval+0.055f)/(1.055f),2.4f));
18747 *ptr = (T)(val*255);
18759 cimg_for(*
this,ptr,T) {
18761 val = (Tfloat)*ptr,
18762 nval = (val<0?0:val>255?255:val)/255,
18763 sval = (Tfloat)(nval<=0.0031308f?nval*12.92f:1.055f*std::pow(nval,0.416667f)-0.055f);
18764 *ptr = (T)(sval*255);
18778 "RGBtoHSV(): Instance is not a RGB image.",
18781 T *p1 =
data(0,0,0,0), *p2 =
data(0,0,0,1), *p3 =
data(0,0,0,2);
18782 for (
unsigned long N = (
unsigned long)_width*_height*_depth; N; --N) {
18787 nR = (R<0?0:(R>255?255:R))/255,
18788 nG = (G<0?0:(G>255?255:G))/255,
18789 nB = (B<0?0:(B>255?255:B))/255,
18792 Tfloat H = 0, S = 0;
18795 f = (nR==m)?(nG-nB):((nG==m)?(nB-nR):(nR-nG)),
18796 i = (Tfloat)((nR==m)?3:((nG==m)?5:1));
18818 "HSVtoRGB(): Instance is not a HSV image.",
18821 T *p1 =
data(0,0,0,0), *p2 =
data(0,0,0,1), *p3 =
data(0,0,0,2);
18822 for (
unsigned long N = (
unsigned long)_width*_height*_depth; N; --N) {
18827 R = 0, G = 0, B = 0;
18828 if (H==0 && S==0) R = G = B = V;
18831 const int i = (int)std::floor(H);
18833 f = (i&1)?(H - i):(1 - H + i),
18838 case 0 : R = V; G = n; B = m;
break;
18839 case 1 : R = n; G = V; B = m;
break;
18840 case 2 : R = m; G = V; B = n;
break;
18841 case 3 : R = m; G = n; B = V;
break;
18842 case 4 : R = n; G = m; B = V;
break;
18843 case 5 : R = V; G = m; B = n;
break;
18846 R*=255; G*=255; B*=255;
18847 *(p1++) = (T)(R<0?0:(R>255?255:R));
18848 *(p2++) = (T)(G<0?0:(G>255?255:G));
18849 *(p3++) = (T)(B<0?0:(B>255?255:B));
18863 "RGBtoHSL(): Instance is not a RGB image.",
18866 T *p1 =
data(0,0,0,0), *p2 =
data(0,0,0,1), *p3 =
data(0,0,0,2);
18867 for (
unsigned long N = (
unsigned long)_width*_height*_depth; N; --N) {
18872 nR = (R<0?0:(R>255?255:R))/255,
18873 nG = (G<0?0:(G>255?255:G))/255,
18874 nB = (B<0?0:(B>255?255:B))/255,
18878 Tfloat H = 0, S = 0;
18879 if (M==m) H = S = 0;
18882 f = (nR==m)?(nG-nB):((nG==m)?(nB-nR):(nR-nG)),
18883 i = (nR==m)?3.0f:((nG==m)?5.0f:1.0f);
18887 S = (2*L<=1)?((M-m)/(M+m)):((M-m)/(2-M-m));
18905 "HSLtoRGB(): Instance is not a HSL image.",
18908 T *p1 =
data(0,0,0,0), *p2 =
data(0,0,0,1), *p3 =
data(0,0,0,2);
18909 for (
unsigned long N = (
unsigned long)_width*_height*_depth; N; --N) {
18914 q = 2*L<1?L*(1+S):(L+S-L*S),
18920 ntr = tr<0?tr+1:(tr>1?tr-1:tr),
18921 ntg = tg<0?tg+1:(tg>1?tg-1:tg),
18922 ntb = tb<0?tb+1:(tb>1?tb-1:tb),
18923 R = 255*(6*ntr<1?p+(q-p)*6*ntr:(2*ntr<1?q:(3*ntr<2?p+(q-p)*6*(2.0f/3-ntr):p))),
18924 G = 255*(6*ntg<1?p+(q-p)*6*ntg:(2*ntg<1?q:(3*ntg<2?p+(q-p)*6*(2.0f/3-ntg):p))),
18925 B = 255*(6*ntb<1?p+(q-p)*6*ntb:(2*ntb<1?q:(3*ntb<2?p+(q-p)*6*(2.0f/3-ntb):p)));
18926 *(p1++) = (T)(R<0?0:(R>255?255:R));
18927 *(p2++) = (T)(G<0?0:(G>255?255:G));
18928 *(p3++) = (T)(B<0?0:(B>255?255:B));
18942 "RGBtoHSI(): Instance is not a RGB image.",
18945 T *p1 =
data(0,0,0,0), *p2 =
data(0,0,0,1), *p3 =
data(0,0,0,2);
18946 for (
unsigned long N = (
unsigned long)_width*_height*_depth; N; --N) {
18951 nR = (R<0?0:(R>255?255:R))/255,
18952 nG = (G<0?0:(G>255?255:G))/255,
18953 nB = (B<0?0:(B>255?255:B))/255,
18955 theta = (Tfloat)(std::acos(0.5f*((nR-nG)+(nR-nB))/std::sqrt(std::pow(nR-nG,2)+(nR-nB)*(nG-nB)))*180/
cimg::PI),
18956 sum = nR + nG + nB;
18957 Tfloat H = 0, S = 0, I = 0;
18958 if (theta>0) H = (nB<=nG)?theta:360-theta;
18959 if (sum>0) S = 1 - 3/sum*m;
18977 "HSItoRGB(): Instance is not a HSI image.",
18980 T *p1 =
data(0,0,0,0), *p2 =
data(0,0,0,1), *p3 =
data(0,0,0,2);
18981 for (
unsigned long N = (
unsigned long)_width*_height*_depth; N; --N) {
18987 R = 0, G = 0, B = 0;
18990 R = (Tfloat)(I*(1+S*std::cos(H*
cimg::PI/180)/std::cos((60-H)*
cimg::PI/180)));
18992 }
else if (H<240) {
18995 G = (Tfloat)(I*(1+S*std::cos(H*
cimg::PI/180)/std::cos((60-H)*
cimg::PI/180)));
19000 B = (Tfloat)(I*(1+S*std::cos(H*
cimg::PI/180)/std::cos((60-H)*
cimg::PI/180)));
19003 R*=255; G*=255; B*=255;
19004 *(p1++) = (T)(R<0?0:(R>255?255:R));
19005 *(p2++) = (T)(G<0?0:(G>255?255:G));
19006 *(p3++) = (T)(B<0?0:(B>255?255:B));
19020 "RGBtoYCbCr(): Instance is not a RGB image.",
19023 T *p1 =
data(0,0,0,0), *p2 =
data(0,0,0,1), *p3 =
data(0,0,0,2);
19024 for (
unsigned long N = (
unsigned long)_width*_height*_depth; N; --N) {
19029 Y = (66*R + 129*G + 25*B + 128)/256 + 16,
19030 Cb = (-38*R - 74*G + 112*B + 128)/256 + 128,
19031 Cr = (112*R - 94*G - 18*B + 128)/256 + 128;
19032 *(p1++) = (T)(Y<0?0:(Y>255?255:Y));
19033 *(p2++) = (T)(Cb<0?0:(Cb>255?255:Cb));
19034 *(p3++) = (T)(Cr<0?0:(Cr>255?255:Cr));
19048 "YCbCrtoRGB(): Instance is not a YCbCr image.",
19051 T *p1 =
data(0,0,0,0), *p2 =
data(0,0,0,1), *p3 =
data(0,0,0,2);
19052 for (
unsigned long N = (
unsigned long)_width*_height*_depth; N; --N) {
19054 Y = (Tfloat)*p1 - 16,
19055 Cb = (Tfloat)*p2 - 128,
19056 Cr = (Tfloat)*p3 - 128,
19057 R = (298*Y + 409*Cr + 128)/256,
19058 G = (298*Y - 100*Cb - 208*Cr + 128)/256,
19059 B = (298*Y + 516*Cb + 128)/256;
19060 *(p1++) = (T)(R<0?0:(R>255?255:R));
19061 *(p2++) = (T)(G<0?0:(G>255?255:G));
19062 *(p3++) = (T)(B<0?0:(B>255?255:B));
19076 "RGBtoYUV(): Instance is not a RGB image.",
19079 T *p1 =
data(0,0,0,0), *p2 =
data(0,0,0,1), *p3 =
data(0,0,0,2);
19080 for (
unsigned long N = (
unsigned long)_width*_height*_depth; N; --N) {
19082 R = (Tfloat)*p1/255,
19083 G = (Tfloat)*p2/255,
19084 B = (Tfloat)*p3/255,
19085 Y = 0.299f*R + 0.587f*G + 0.114f*B;
19087 *(p2++) = (T)(0.492f*(B-Y));
19088 *(p3++) = (T)(0.877*(R-Y));
19102 "YUVtoRGB(): Instance is not a YUV image.",
19105 T *p1 =
data(0,0,0,0), *p2 =
data(0,0,0,1), *p3 =
data(0,0,0,2);
19106 for (
unsigned long N = (
unsigned long)_width*_height*_depth; N; --N) {
19111 R = (Y + 1.140f*V)*255,
19112 G = (Y - 0.395f*U - 0.581f*V)*255,
19113 B = (Y + 2.032f*U)*255;
19114 *(p1++) = (T)(R<0?0:(R>255?255:R));
19115 *(p2++) = (T)(G<0?0:(G>255?255:G));
19116 *(p3++) = (T)(B<0?0:(B>255?255:B));
19130 "RGBtoCMY(): Instance is not a RGB image.",
19133 T *p1 =
data(0,0,0,0), *p2 =
data(0,0,0,1), *p3 =
data(0,0,0,2);
19134 for (
unsigned long N = (
unsigned long)_width*_height*_depth; N; --N) {
19142 *(p1++) = (T)(C<0?0:(C>255?255:C));
19143 *(p2++) = (T)(M<0?0:(M>255?255:M));
19144 *(p3++) = (T)(Y<0?0:(Y>255?255:Y));
19158 "CMYtoRGB(): Instance is not a CMY image.",
19161 T *p1 =
data(0,0,0,0), *p2 =
data(0,0,0,1), *p3 =
data(0,0,0,2);
19162 for (
unsigned long N = (
unsigned long)_width*_height*_depth; N; --N) {
19170 *(p1++) = (T)(R<0?0:(R>255?255:R));
19171 *(p2++) = (T)(G<0?0:(G>255?255:G));
19172 *(p3++) = (T)(B<0?0:(B>255?255:B));
19191 "CMYtoCMYK(): Instance is not a CMY image.",
19195 const T *ps1 =
data(0,0,0,0), *ps2 =
data(0,0,0,1), *ps3 =
data(0,0,0,2);
19196 Tfloat *pd1 = res.data(0,0,0,0), *pd2 = res.data(0,0,0,1), *pd3 = res.data(0,0,0,2), *pd4 = res.data(0,0,0,3);
19197 for (
unsigned long N = (
unsigned long)_width*_height*_depth; N; --N) {
19199 C = (Tfloat)*(ps1++),
19200 M = (Tfloat)*(ps2++),
19201 Y = (Tfloat)*(ps3++),
19203 if (K>=255) C = M = Y = 0;
19204 else {
const Tfloat K1 = 255 - K; C = 255*(C - K)/K1; M = 255*(M - K)/K1; Y = 255*(Y - K)/K1; }
19205 *(pd1++) = (Tfloat)(C<0?0:(C>255?255:C));
19206 *(pd2++) = (Tfloat)(M<0?0:(M>255?255:M));
19207 *(pd3++) = (Tfloat)(Y<0?0:(Y>255?255:Y));
19208 *(pd4++) = (Tfloat)(K<0?0:(K>255?255:K));
19222 "CMYKtoCMY(): Instance is not a CMYK image.",
19226 const T *ps1 =
data(0,0,0,0), *ps2 =
data(0,0,0,1), *ps3 =
data(0,0,0,2), *ps4 =
data(0,0,0,3);
19227 Tfloat *pd1 = res.data(0,0,0,0), *pd2 = res.data(0,0,0,1), *pd3 = res.data(0,0,0,2);
19228 for (
unsigned long N = (
unsigned long)_width*_height*_depth; N; --N) {
19230 C = (Tfloat)*(ps1++),
19231 M = (Tfloat)*(ps2++),
19232 Y = (Tfloat)*(ps3++),
19233 K = (Tfloat)*(ps4++),
19238 *(pd1++) = (Tfloat)(nC<0?0:(nC>255?255:nC));
19239 *(pd2++) = (Tfloat)(nM<0?0:(nM>255?255:nM));
19240 *(pd3++) = (Tfloat)(nY<0?0:(nY>255?255:nY));
19252 "RGBtoXYZ(): Instance is not a RGB image.",
19255 T *p1 =
data(0,0,0,0), *p2 =
data(0,0,0,1), *p3 =
data(0,0,0,2);
19256 for (
unsigned long N = (
unsigned long)_width*_height*_depth; N; --N) {
19258 R = (Tfloat)*p1/255,
19259 G = (Tfloat)*p2/255,
19260 B = (Tfloat)*p3/255;
19261 *(p1++) = (T)(0.412453f*R + 0.357580f*G + 0.180423f*B);
19262 *(p2++) = (T)(0.212671f*R + 0.715160f*G + 0.072169f*B);
19263 *(p3++) = (T)(0.019334f*R + 0.119193f*G + 0.950227f*B);
19277 "XYZtoRGB(): Instance is not a XYZ image.",
19280 T *p1 =
data(0,0,0,0), *p2 =
data(0,0,0,1), *p3 =
data(0,0,0,2);
19281 for (
unsigned long N = (
unsigned long)_width*_height*_depth; N; --N) {
19283 X = (Tfloat)*p1*255,
19284 Y = (Tfloat)*p2*255,
19285 Z = (Tfloat)*p3*255,
19286 R = 3.240479f*X - 1.537150f*Y - 0.498535f*Z,
19287 G = -0.969256f*X + 1.875992f*Y + 0.041556f*Z,
19288 B = 0.055648f*X - 0.204043f*Y + 1.057311f*Z;
19289 *(p1++) = (T)(R<0?0:(R>255?255:R));
19290 *(p2++) = (T)(G<0?0:(G>255?255:G));
19291 *(p3++) = (T)(B<0?0:(B>255?255:B));
19303 #define _cimg_Labf(x) ((x)>=0.008856f?(std::pow(x,(Tfloat)1/3)):(7.787f*(x)+16.0f/116))
19307 "XYZtoLab(): Instance is not a XYZ image.",
19311 Xn = (Tfloat)(0.412453f + 0.357580f + 0.180423f),
19312 Yn = (Tfloat)(0.212671f + 0.715160f + 0.072169f),
19313 Zn = (Tfloat)(0.019334f + 0.119193f + 0.950227f);
19314 T *p1 =
data(0,0,0,0), *p2 =
data(0,0,0,1), *p3 =
data(0,0,0,2);
19315 for (
unsigned long N = (
unsigned long)_width*_height*_depth; N; --N) {
19320 XXn = X/Xn, YYn = Y/Yn, ZZn = Z/Zn,
19321 fX = (Tfloat)_cimg_Labf(XXn),
19322 fY = (Tfloat)_cimg_Labf(YYn),
19323 fZ = (Tfloat)_cimg_Labf(ZZn);
19324 *(p1++) = (T)
cimg::max(0.0f,116*fY - 16);
19325 *(p2++) = (T)(500*(fX - fY));
19326 *(p3++) = (T)(200*(fY - fZ));
19338 #define _cimg_Labfi(x) ((x)>=0.206893f?((x)*(x)*(x)):(((x)-16.0f/116)/7.787f))
19342 "LabtoXYZ(): Instance is not a Lab image.",
19346 Xn = (Tfloat)(0.412453f + 0.357580f + 0.180423f),
19347 Yn = (Tfloat)(0.212671f + 0.715160f + 0.072169f),
19348 Zn = (Tfloat)(0.019334f + 0.119193f + 0.950227f);
19349 T *p1 =
data(0,0,0,0), *p2 =
data(0,0,0,1), *p3 =
data(0,0,0,2);
19350 for (
unsigned long N = (
unsigned long)_width*_height*_depth; N; --N) {
19356 Y = (Tfloat)(Yn*_cimg_Labfi(cY)),
19357 pY = (Tfloat)std::pow(Y/Yn,(Tfloat)1/3),
19378 "XYZtoxyY(): Instance is not a XYZ image.",
19381 T *p1 =
data(0,0,0,0), *p2 =
data(0,0,0,1), *p3 =
data(0,0,0,2);
19382 for (
unsigned long N = (
unsigned long)_width*_height*_depth; N; --N) {
19388 nsum = sum>0?sum:1;
19389 *(p1++) = (T)(X/nsum);
19390 *(p2++) = (T)(Y/nsum);
19405 "xyYtoXYZ(): Instance is not a xyY image.",
19408 T *p1 =
data(0,0,0,0), *p2 =
data(0,0,0,1), *p3 =
data(0,0,0,2);
19409 for (
unsigned long N = (
unsigned long)_width*_height*_depth; N; --N) {
19415 *(p1++) = (T)(px*Y/ny);
19417 *(p3++) = (T)((1-px-py)*Y/ny);
19499 "RGBtoBayer(): Instance is not a RGB image.",
19502 CImg<T> res(_width,_height,_depth,1);
19503 const T *ptr_r =
data(0,0,0,0), *ptr_g =
data(0,0,0,1), *ptr_b =
data(0,0,0,2);
19504 T *ptrd = res._data;
19505 cimg_forXYZ(*
this,x,y,z) {
19507 if (x%2) *(ptrd++) = *ptr_b;
19508 else *(ptrd++) = *ptr_g;
19510 if (x%2) *(ptrd++) = *ptr_g;
19511 else *(ptrd++) = *ptr_r;
19513 ++ptr_r; ++ptr_g; ++ptr_b;
19527 "BayertoRGB(): Instance is not a Bayer image.",
19532 Tuchar *ptr_r = res.data(0,0,0,0), *ptr_g = res.data(0,0,0,1), *ptr_b = res.data(0,0,0,2);
19533 switch (interpolation_type) {
19538 cimg_forXYZ(*
this,x,y,z) {
19539 const int _p1x = x?x-1:1, _p1y = y?y-1:1, _n1x = x<
width()-1?x+1:x-1, _n1y = y<
height()-1?y+1:y-1;
19540 cimg_get3x3(*
this,x,y,z,0,I,T);
19543 const Tfloat alpha =
cimg::sqr((Tfloat)Inc - Ipc), beta =
cimg::sqr((Tfloat)Icn - Icp), cx = 1/(1+alpha), cy = 1/(1+beta);
19544 *ptr_g = (Tuchar)((cx*(Inc+Ipc) + cy*(Icn+Icp))/(2*(cx+cy)));
19545 }
else *ptr_g = (Tuchar)Icc;
19547 if (x%2) *ptr_g = (Tuchar)Icc;
19549 const Tfloat alpha =
cimg::sqr((Tfloat)Inc - Ipc), beta =
cimg::sqr((Tfloat)Icn - Icp), cx = 1/(1+alpha), cy = 1/(1+beta);
19550 *ptr_g = (Tuchar)((cx*(Inc+Ipc) + cy*(Icn+Icp))/(2*(cx+cy)));
19555 cimg_forXYZ(*
this,x,y,z) {
19556 const int _p1x = x?x-1:1, _p1y = y?y-1:1, _n1x = x<
width()-1?x+1:x-1, _n1y = y<
height()-1?y+1:y-1;
19557 cimg_get3x3(*
this,x,y,z,0,I,T);
19558 cimg_get3x3(res,x,y,z,1,G,T);
19560 if (x%2) *ptr_b = (Tuchar)Icc;
19561 else { *ptr_r = (Tuchar)((Icn+Icp)/2); *ptr_b = (Tuchar)((Inc+Ipc)/2); }
19563 if (x%2) { *ptr_r = (Tuchar)((Inc+Ipc)/2); *ptr_b = (Tuchar)((Icn+Icp)/2); }
19564 else *ptr_r = (Tuchar)Icc;
19568 ptr_r = res.data(0,0,0,0);
19569 ptr_g = res.data(0,0,0,1);
19570 ptr_b = res.data(0,0,0,2);
19571 cimg_forXYZ(*
this,x,y,z) {
19572 const int _p1x = x?x-1:1, _p1y = y?y-1:1, _n1x = x<
width()-1?x+1:x-1, _n1y = y<
height()-1?y+1:y-1;
19573 cimg_get3x3(res,x,y,z,0,R,T);
19574 cimg_get3x3(res,x,y,z,1,G,T);
19575 cimg_get3x3(res,x,y,z,2,B,T);
19578 const float alpha = (float)
cimg::sqr(Rnc-Rpc), beta = (float)
cimg::sqr(Rcn-Rcp), cx = 1/(1+alpha), cy = 1/(1+beta);
19579 *ptr_r = (Tuchar)((cx*(Rnc+Rpc) + cy*(Rcn+Rcp))/(2*(cx+cy)));
19583 const float alpha = (float)
cimg::sqr(Bnc-Bpc), beta = (float)
cimg::sqr(Bcn-Bcp), cx = 1/(1+alpha), cy = 1/(1+beta);
19584 *ptr_b = (Tuchar)((cx*(Bnc+Bpc) + cy*(Bcn+Bcp))/(2*(cx+cy)));
19587 ++ptr_r; ++ptr_g; ++ptr_b;
19591 cimg_forXYZ(*
this,x,y,z) {
19592 const int _p1x = x?x-1:1, _p1y = y?y-1:1, _n1x = x<
width()-1?x+1:x-1, _n1y = y<
height()-1?y+1:y-1;
19593 cimg_get3x3(*
this,x,y,z,0,I,T);
19595 if (x%2) { *ptr_r = (Tuchar)((Ipp+Inn+Ipn+Inp)/4); *ptr_g = (Tuchar)((Inc+Ipc+Icn+Icp)/4); *ptr_b = (Tuchar)Icc; }
19596 else { *ptr_r = (Tuchar)((Icp+Icn)/2); *ptr_g = (Tuchar)Icc; *ptr_b = (Tuchar)((Inc+Ipc)/2); }
19598 if (x%2) { *ptr_r = (Tuchar)((Ipc+Inc)/2); *ptr_g = (Tuchar)Icc; *ptr_b = (Tuchar)((Icn+Icp)/2); }
19599 else { *ptr_r = (Tuchar)Icc; *ptr_g = (Tuchar)((Inc+Ipc+Icn+Icp)/4); *ptr_b = (Tuchar)((Ipp+Inn+Ipn+Inp)/4); }
19601 ++ptr_r; ++ptr_g; ++ptr_b;
19605 cimg_forXYZ(*
this,x,y,z) {
19606 const int _p1x = x?x-1:1, _p1y = y?y-1:1, _n1x = x<
width()-1?x+1:x-1, _n1y = y<
height()-1?y+1:y-1;
19607 cimg_get3x3(*
this,x,y,z,0,I,T);
19609 if (x%2) { *ptr_r = (Tuchar)
cimg::min(Ipp,Inn,Ipn,Inp); *ptr_g = (Tuchar)
cimg::min(Inc,Ipc,Icn,Icp); *ptr_b = (Tuchar)Icc; }
19610 else { *ptr_r = (Tuchar)
cimg::min(Icn,Icp); *ptr_g = (Tuchar)Icc; *ptr_b = (Tuchar)
cimg::min(Inc,Ipc); }
19612 if (x%2) { *ptr_r = (Tuchar)
cimg::min(Inc,Ipc); *ptr_g = (Tuchar)Icc; *ptr_b = (Tuchar)
cimg::min(Icn,Icp); }
19613 else { *ptr_r = (Tuchar)Icc; *ptr_g = (Tuchar)
cimg::min(Inc,Ipc,Icn,Icp); *ptr_b = (Tuchar)
cimg::min(Ipp,Inn,Ipn,Inp); }
19615 ++ptr_r; ++ptr_g; ++ptr_b;
19619 const T *ptrs = _data;
19621 cimg_forXYZ(*
this,x,y,z) {
19622 const T val = *(ptrs++);
19623 if (y%2) {
if (x%2) *ptr_b = val;
else *ptr_g = val; }
else {
if (x%2) *ptr_g = val;
else *ptr_r = val; }
19624 ++ptr_r; ++ptr_g; ++ptr_b;
19638 static float _cimg_lanczos(
const float x) {
19639 if (x<=-2 || x>=2)
return 0;
19640 const float a = (float)
cimg::PI*x, b = 0.5f*a;
19641 return (
float)(x?std::sin(a)*std::sin(b)/(a*b):1);
19667 const int size_z=-100,
const int size_c=-100,
19668 const int interpolation_type=1,
const unsigned int boundary_conditions=0,
19669 const float centering_x = 0,
const float centering_y = 0,
19670 const float centering_z = 0,
const float centering_c = 0) {
19671 if (!size_x || !size_y || !size_z || !size_c)
return assign();
19673 _sx = (
unsigned int)(size_x<0?-size_x*
width()/100:size_x),
19674 _sy = (
unsigned int)(size_y<0?-size_y*
height()/100:size_y),
19675 _sz = (
unsigned int)(size_z<0?-size_z*
depth()/100:size_z),
19676 _sc = (
unsigned int)(size_c<0?-size_c*
spectrum()/100:size_c),
19677 sx = _sx?_sx:1, sy = _sy?_sy:1, sz = _sz?_sz:1, sc = _sc?_sc:1;
19678 if (sx==_width && sy==_height && sz==_depth && sc==_spectrum)
return *
this;
19680 if (interpolation_type==-1 && sx*sy*sz*sc==
size()) {
19681 _width = sx; _height = sy; _depth = sz; _spectrum = sc;
19684 return get_resize(sx,sy,sz,sc,interpolation_type,boundary_conditions,centering_x,centering_y,centering_z,centering_c).move_to(*
this);
19689 const int size_z = -100,
const int size_c = -100,
19690 const int interpolation_type=1,
const unsigned int boundary_conditions=0,
19691 const float centering_x = 0,
const float centering_y = 0,
19692 const float centering_z = 0,
const float centering_c = 0)
const {
19693 if (centering_x<0 || centering_x>1 || centering_y<0 || centering_y>1 ||
19694 centering_z<0 || centering_z>1 || centering_c<0 || centering_c>1)
19696 "resize(): Specified centering arguments (%g,%g,%g,%g) are outside range [0,1].",
19698 centering_x,centering_y,centering_z,centering_c);
19700 if (!size_x || !size_y || !size_z || !size_c)
return CImg<T>();
19702 _sx = (
unsigned int)(size_x<0?-size_x*
width()/100:size_x),
19703 _sy = (
unsigned int)(size_y<0?-size_y*
height()/100:size_y),
19704 _sz = (
unsigned int)(size_z<0?-size_z*
depth()/100:size_z),
19705 _sc = (
unsigned int)(size_c<0?-size_c*
spectrum()/100:size_c),
19706 sx = _sx?_sx:1, sy = _sy?_sy:1, sz = _sz?_sz:1, sc = _sc?_sc:1;
19707 if (sx==_width && sy==_height && sz==_depth && sc==_spectrum)
return +*
this;
19711 switch (interpolation_type) {
19716 std::memcpy(res.assign(sx,sy,sz,sc,0)._data,_data,
sizeof(T)*
cimg::min(
size(),sx*sy*sz*sc));
19723 xc = (int)(centering_x*((
int)sx -
width())),
19724 yc = (
int)(centering_y*((int)sy -
height())),
19725 zc = (int)(centering_z*((
int)sz -
depth())),
19726 cc = (int)(centering_c*((
int)sc -
spectrum()));
19728 switch (boundary_conditions) {
19730 res.assign(sx,sy,sz,sc);
19736 for (
int c = c0; c<(int)sc; c+=
spectrum())
19737 for (
int z = z0; z<(int)sz; z+=
depth())
19738 for (
int y = y0; y<(int)sy; y+=
height())
19739 for (
int x = x0; x<(int)sx; x+=
width())
19740 res.draw_image(x,y,z,c,*
this);
19743 res.assign(sx,sy,sz,sc).draw_image(xc,yc,zc,cc,*
this);
19747 for (
int x = xc-1; x>=0; --x) res.draw_image(x,yc,zc,cc,sprite);
19749 if (xc+
width()<(
int)sx) {
19751 for (
int x = xc+
width(); x<(int)sx; ++x) res.draw_image(x,yc,zc,cc,sprite);
19754 res.get_crop(0,yc,zc,cc,sx-1,yc,zc+
depth()-1,cc+
spectrum()-1).move_to(sprite);
19755 for (
int y = yc-1; y>=0; --y) res.draw_image(0,y,zc,cc,sprite);
19757 if (yc+
height()<(
int)sy) {
19759 for (
int y = yc+
height(); y<(int)sy; ++y) res.draw_image(0,y,zc,cc,sprite);
19762 res.get_crop(0,0,zc,cc,sx-1,sy-1,zc,cc+
spectrum()-1).move_to(sprite);
19763 for (
int z = zc-1; z>=0; --z) res.draw_image(0,0,z,cc,sprite);
19765 if (zc+
depth()<(
int)sz) {
19766 res.get_crop(0,0,zc+
depth()-1,cc,sx-1,sy-1,zc+
depth()-1,cc+
spectrum()-1).move_to(sprite);
19767 for (
int z = zc+
depth(); z<(int)sz; ++z) res.draw_image(0,0,z,cc,sprite);
19770 res.get_crop(0,0,0,cc,sx-1,sy-1,sz-1,cc).move_to(sprite);
19771 for (
int c = cc-1; c>=0; --c) res.draw_image(0,0,0,c,sprite);
19774 res.get_crop(0,0,0,cc+
spectrum()-1,sx-1,sy-1,sz-1,cc+
spectrum()-1).move_to(sprite);
19775 for (
int c = cc+
spectrum(); c<(int)sc; ++c) res.draw_image(0,0,0,c,sprite);
19779 res.assign(sx,sy,sz,sc,0).draw_image(xc,yc,zc,cc,*
this);
19787 res.assign(sx,sy,sz,sc);
19788 CImg<ulongT> off_x(sx), off_y(sy+1), off_z(sz+1), off_c(sc+1);
19789 unsigned long *poff_x, *poff_y, *poff_z, *poff_c, curr, old;
19790 const unsigned long
19791 wh = (
unsigned long)_width*_height,
19792 whd = (
unsigned long)_width*_height*_depth,
19793 sxy = (
unsigned long)sx*sy,
19794 sxyz = (
unsigned long)sx*sy*sz;
19795 if (sx==_width) off_x.fill(1);
19797 poff_x = off_x._data; curr = 0;
19798 cimg_forX(res,x) { old = curr; curr = ((x+1LU)*_width/sx); *(poff_x++) = curr - old; }
19800 if (sy==_height) off_y.fill(_width);
19802 poff_y = off_y._data; curr = 0;
19803 cimg_forY(res,y) { old = curr; curr = ((y+1LU)*_height/sy); *(poff_y++) = _width*(curr - old); } *poff_y = 0;
19805 if (sz==_depth) off_z.fill(wh);
19807 poff_z = off_z._data; curr = 0;
19808 cimg_forZ(res,z) { old = curr; curr = ((z+1LU)*_depth/sz); *(poff_z++) = wh*(curr - old); } *poff_z = 0;
19810 if (sc==_spectrum) off_c.fill(whd);
19812 poff_c = off_c._data; curr = 0;
19813 cimg_forC(res,c) { old = curr; curr = ((c+1LU)*_spectrum/sc); *(poff_c++) = whd*(curr - old); } *poff_c = 0;
19816 T *ptrd = res._data;
19817 const T* ptrv = _data;
19818 poff_c = off_c._data;
19819 for (
unsigned int c = 0; c<sc; ) {
19820 const T *ptrz = ptrv;
19821 poff_z = off_z._data;
19822 for (
unsigned int z = 0; z<sz; ) {
19823 const T *ptry = ptrz;
19824 poff_y = off_y._data;
19825 for (
unsigned int y = 0; y<sy; ) {
19826 const T *ptrx = ptry;
19827 poff_x = off_x._data;
19828 cimg_forX(res,x) { *(ptrd++) = *ptrx; ptrx+=*(poff_x++); }
19830 unsigned long dy = *(poff_y++);
19831 for (;!dy && y<dy; std::memcpy(ptrd,ptrd - sx,
sizeof(T)*sx), ++y, ptrd+=sx, dy = *(poff_y++)) {}
19835 unsigned long dz = *(poff_z++);
19836 for (;!dz && z<dz; std::memcpy(ptrd,ptrd-sxy,
sizeof(T)*sxy), ++z, ptrd+=sxy, dz = *(poff_z++)) {}
19840 unsigned long dc = *(poff_c++);
19841 for (;!dc && c<dc; std::memcpy(ptrd,ptrd-sxyz,
sizeof(T)*sxyz), ++c, ptrd+=sxyz, dc = *(poff_c++)) {}
19849 bool instance_first =
true;
19852 for (
unsigned int a = _width*sx, b = _width, c = sx, s = 0, t = 0; a; ) {
19855 cimg_forYZC(tmp,y,z,v) tmp(t,y,z,v)+=(Tfloat)(*
this)(s,y,z,v)*d;
19856 if (!b) { cimg_forYZC(tmp,y,z,v) tmp(t,y,z,v)/=_width; ++t; b = _width; }
19857 if (!c) { ++s; c = sx; }
19860 instance_first =
false;
19864 for (
unsigned int a = _height*sy, b = _height, c = sy, s = 0, t = 0; a; ) {
19867 if (instance_first) cimg_forXZC(tmp,x,z,v) tmp(x,t,z,v)+=(Tfloat)(*
this)(x,s,z,v)*d;
19868 else cimg_forXZC(tmp,x,z,v) tmp(x,t,z,v)+=(Tfloat)res(x,s,z,v)*d;
19869 if (!b) { cimg_forXZC(tmp,x,z,v) tmp(x,t,z,v)/=_height; ++t; b = _height; }
19870 if (!c) { ++s; c = sy; }
19873 instance_first =
false;
19877 for (
unsigned int a = _depth*sz, b = _depth, c = sz, s = 0, t = 0; a; ) {
19880 if (instance_first) cimg_forXYC(tmp,x,y,v) tmp(x,y,t,v)+=(Tfloat)(*
this)(x,y,s,v)*d;
19881 else cimg_forXYC(tmp,x,y,v) tmp(x,y,t,v)+=(Tfloat)res(x,y,s,v)*d;
19882 if (!b) { cimg_forXYC(tmp,x,y,v) tmp(x,y,t,v)/=_depth; ++t; b = _depth; }
19883 if (!c) { ++s; c = sz; }
19886 instance_first =
false;
19888 if (sc!=_spectrum) {
19890 for (
unsigned int a = _spectrum*sc, b = _spectrum, c = sc, s = 0, t = 0; a; ) {
19893 if (instance_first) cimg_forXYZ(tmp,x,y,z) tmp(x,y,z,t)+=(Tfloat)(*
this)(x,y,z,s)*d;
19894 else cimg_forXYZ(tmp,x,y,z) tmp(x,y,z,t)+=(Tfloat)res(x,y,z,s)*d;
19895 if (!b) { cimg_forXYZ(tmp,x,y,z) tmp(x,y,z,t)/=_spectrum; ++t; b = _spectrum; }
19896 if (!c) { ++s; c = sc; }
19899 instance_first =
false;
19908 unsigned int *poff;
19909 float *pfoff, old, curr;
19910 CImg<T> resx, resy, resz, resc;
19914 if (_width==1)
get_resize(sx,_height,_depth,_spectrum,1).move_to(resx);
19916 const float fx = (!boundary_conditions && sx>_width)?(sx>1?(_width-1.0f)/(sx-1):0):(float)_width/sx;
19917 resx.assign(sx,_height,_depth,_spectrum);
19918 curr = old = 0; poff = off._data; pfoff = foff._data;
19919 cimg_forX(resx,x) { *(pfoff++) = curr - (
unsigned int)curr; old = curr; curr+=fx; *(poff++) = (
unsigned int)curr - (
unsigned int)old; }
19921 const T *ptrs0 = _data;
19922 cimg_forYZC(resx,y,z,c) {
19923 poff = off._data; pfoff = foff._data;
19924 const T *ptrs = ptrs0, *
const ptrsmax = ptrs0 + (_width-1);
19925 cimg_forX(resx,x) {
19926 const float alpha = *(pfoff++);
19927 const T val1 = *ptrs, val2 = ptrs<ptrsmax?*(ptrs+1):val1;
19928 *(ptrd++) = (T)((1-alpha)*val1 + alpha*val2);
19934 }
else resx.assign(*
this,
true);
19937 if (_height==1) resx.get_resize(sx,sy,_depth,_spectrum,1).move_to(resy);
19939 const float fy = (!boundary_conditions && sy>_height)?(sy>1?(_height-1.0f)/(sy-1):0):(float)_height/sy;
19940 resy.assign(sx,sy,_depth,_spectrum);
19941 curr = old = 0; poff = off._data; pfoff = foff._data;
19942 cimg_forY(resy,y) { *(pfoff++) = curr - (
unsigned int)curr; old = curr; curr+=fy; *(poff++) = sx*((
unsigned int)curr-(
unsigned int)old); }
19943 cimg_forXZC(resy,x,z,c) {
19944 ptrd = resy.data(x,0,z,c);
19945 const T *ptrs = resx.data(x,0,z,c), *
const ptrsmax = ptrs + (_height-1)*sx;
19946 poff = off._data; pfoff = foff._data;
19947 cimg_forY(resy,y) {
19948 const float alpha = *(pfoff++);
19949 const T val1 = *ptrs, val2 = ptrs<ptrsmax?*(ptrs+sx):val1;
19950 *ptrd = (T)((1-alpha)*val1 + alpha*val2);
19957 }
else resy.assign(resx,
true);
19960 if (_depth==1) resy.get_resize(sx,sy,sz,_spectrum,1).move_to(resz);
19962 const float fz = (!boundary_conditions && sz>_depth)?(sz>1?(_depth-1.0f)/(sz-1):0):(float)_depth/sz;
19963 const unsigned int sxy = sx*sy;
19964 resz.assign(sx,sy,sz,_spectrum);
19965 curr = old = 0; poff = off._data; pfoff = foff._data;
19966 cimg_forZ(resz,z) { *(pfoff++) = curr - (
unsigned int)curr; old = curr; curr+=fz; *(poff++) = sxy*((
unsigned int)curr - (
unsigned int)old); }
19967 cimg_forXYC(resz,x,y,c) {
19968 ptrd = resz.data(x,y,0,c);
19969 const T *ptrs = resy.data(x,y,0,c), *
const ptrsmax = ptrs + (_depth-1)*sxy;
19970 poff = off._data; pfoff = foff._data;
19971 cimg_forZ(resz,z) {
19972 const float alpha = *(pfoff++);
19973 const T val1 = *ptrs, val2 = ptrs<ptrsmax?*(ptrs+sxy):val1;
19974 *ptrd = (T)((1-alpha)*val1 + alpha*val2);
19981 }
else resz.assign(resy,
true);
19983 if (sc!=_spectrum) {
19984 if (_spectrum==1) resz.get_resize(sx,sy,sz,sc,1).move_to(resc);
19986 const float fc = (!boundary_conditions && sc>_spectrum)?(sc>1?(_spectrum-1.0f)/(sc-1):0):(float)_spectrum/sc;
19987 const unsigned int sxyz = sx*sy*sz;
19988 resc.assign(sx,sy,sz,sc);
19989 curr = old = 0; poff = off._data; pfoff = foff._data;
19990 cimg_forC(resc,c) { *(pfoff++) = curr - (
unsigned int)curr; old = curr; curr+=fc; *(poff++) = sxyz*((
unsigned int)curr - (
unsigned int)old); }
19991 cimg_forXYZ(resc,x,y,z) {
19992 ptrd = resc.data(x,y,z,0);
19993 const T *ptrs = resz.data(x,y,z,0), *
const ptrsmax = ptrs + (_spectrum-1)*sxyz;
19994 poff = off._data; pfoff = foff._data;
19995 cimg_forC(resc,c) {
19996 const float alpha = *(pfoff++);
19997 const T val1 = *ptrs, val2 = ptrs<ptrsmax?*(ptrs+sxyz):val1;
19998 *ptrd = (T)((1-alpha)*val1 + alpha*val2);
20005 }
else resc.assign(resz,
true);
20006 return resc._is_shared?(resz._is_shared?(resy._is_shared?(resx._is_shared?(+(*this)):resx):resy):resz):resc;
20012 CImg<T> resx, resy, resz, resc;
20014 if (sx<_width)
get_resize(sx,_height,_depth,_spectrum,1).move_to(resx);
20016 resx.assign(sx,_height,_depth,_spectrum,0);
20017 const int dx = sx*2, dy =
width()*2;
20018 int err = dy + centering_x*(sx*dy/
width() - dy), xs = 0;
20019 cimg_forX(resx,x)
if ((err-=dy)<=0) {
20020 cimg_forYZC(resx,y,z,c) resx(x,y,z,c) = (*this)(xs,y,z,c);
20025 }
else resx.assign(*
this,
true);
20028 if (sy<_height) resx.get_resize(sx,sy,_depth,_spectrum,1).move_to(resy);
20030 resy.assign(sx,sy,_depth,_spectrum,0);
20031 const int dx = sy*2, dy =
height()*2;
20032 int err = dy + centering_y*(sy*dy/
height() - dy), ys = 0;
20033 cimg_forY(resy,y)
if ((err-=dy)<=0) {
20034 cimg_forXZC(resy,x,z,c) resy(x,y,z,c) = resx(x,ys,z,c);
20040 }
else resy.assign(resx,
true);
20043 if (sz<_depth) resy.get_resize(sx,sy,sz,_spectrum,1).move_to(resz);
20045 resz.assign(sx,sy,sz,_spectrum,0);
20046 const int dx = sz*2, dy =
depth()*2;
20047 int err = dy + centering_z*(sz*dy/
depth() - dy), zs = 0;
20048 cimg_forZ(resz,z)
if ((err-=dy)<=0) {
20049 cimg_forXYC(resz,x,y,c) resz(x,y,z,c) = resy(x,y,zs,c);
20055 }
else resz.assign(resy,
true);
20057 if (sc!=_spectrum) {
20058 if (sc<_spectrum) resz.get_resize(sx,sy,sz,sc,1).move_to(resc);
20060 resc.assign(sx,sy,sz,sc,0);
20061 const int dx = sc*2, dy =
spectrum()*2;
20062 int err = dy + centering_c*(sc*dy/
spectrum() - dy), cs = 0;
20063 cimg_forC(resc,c)
if ((err-=dy)<=0) {
20064 cimg_forXYZ(resc,x,y,z) resc(x,y,z,c) = resz(x,y,z,cs);
20070 }
else resc.assign(resz,
true);
20072 return resc._is_shared?(resz._is_shared?(resy._is_shared?(resx._is_shared?(+(*this)):resx):resy):resz):resc;
20081 unsigned int *poff;
20082 float *pfoff, old, curr;
20083 CImg<T> resx, resy, resz, resc;
20087 if (_width==1)
get_resize(sx,_height,_depth,_spectrum,1).move_to(resx);
20089 const float fx = (!boundary_conditions && sx>_width)?(sx>1?(_width-1.0f)/(sx-1):0):(float)_width/sx;
20090 resx.assign(sx,_height,_depth,_spectrum);
20091 curr = old = 0; poff = off._data; pfoff = foff._data;
20092 cimg_forX(resx,x) { *(pfoff++) = curr - (
unsigned int)curr; old = curr; curr+=fx; *(poff++) = (
unsigned int)curr - (
unsigned int)old; }
20094 const T *ptrs0 = _data;
20095 cimg_forYZC(resx,y,z,c) {
20096 poff = off._data; pfoff = foff._data;
20097 const T *ptrs = ptrs0, *
const ptrsmax = ptrs0 + (_width-2);
20098 cimg_forX(resx,x) {
20099 const float t = *(pfoff++);
20101 val1 = (Tfloat)*ptrs,
20102 val0 = ptrs>ptrs0?(Tfloat)*(ptrs-1):val1,
20103 val2 = ptrs<=ptrsmax?(Tfloat)*(ptrs+1):val1,
20104 val3 = ptrs<ptrsmax?(Tfloat)*(ptrs+2):val2,
20105 val = val1 + 0.5f*(t*(-val0+val2) + t*t*(2*val0-5*val1+4*val2-val3) + t*t*t*(-val0+3*val1-3*val2+val3));
20106 *(ptrd++) = (T)(val<vmin?vmin:val>vmax?vmax:val);
20112 }
else resx.assign(*
this,
true);
20115 if (_height==1) resx.get_resize(sx,sy,_depth,_spectrum,1).move_to(resy);
20117 const float fy = (!boundary_conditions && sy>_height)?(sy>1?(_height-1.0f)/(sy-1):0):(float)_height/sy;
20118 resy.assign(sx,sy,_depth,_spectrum);
20119 curr = old = 0; poff = off._data; pfoff = foff._data;
20120 cimg_forY(resy,y) { *(pfoff++) = curr - (
unsigned int)curr; old = curr; curr+=fy; *(poff++) = sx*((
unsigned int)curr-(
unsigned int)old); }
20121 cimg_forXZC(resy,x,z,c) {
20122 ptrd = resy.data(x,0,z,c);
20123 const T *
const ptrs0 = resx.data(x,0,z,c), *ptrs = ptrs0, *
const ptrsmax = ptrs0 + (_height-2)*sx;
20124 poff = off._data; pfoff = foff._data;
20125 cimg_forY(resy,y) {
20126 const float t = *(pfoff++);
20128 val1 = (Tfloat)*ptrs,
20129 val0 = ptrs>ptrs0?(Tfloat)*(ptrs-sx):val1,
20130 val2 = ptrs<=ptrsmax?(Tfloat)*(ptrs+sx):val1,
20131 val3 = ptrs<ptrsmax?(Tfloat)*(ptrs+2*sx):val2,
20132 val = val1 + 0.5f*(t*(-val0+val2) + t*t*(2*val0-5*val1+4*val2-val3) + t*t*t*(-val0+3*val1-3*val2+val3));
20133 *ptrd = (T)(val<vmin?vmin:val>vmax?vmax:val);
20140 }
else resy.assign(resx,
true);
20143 if (_depth==1) resy.get_resize(sx,sy,sz,_spectrum,1).move_to(resz);
20145 const float fz = (!boundary_conditions && sz>_depth)?(sz>1?(_depth-1.0f)/(sz-1):0):(float)_depth/sz;
20146 const unsigned int sxy = sx*sy;
20147 resz.assign(sx,sy,sz,_spectrum);
20148 curr = old = 0; poff = off._data; pfoff = foff._data;
20149 cimg_forZ(resz,z) { *(pfoff++) = curr - (
unsigned int)curr; old = curr; curr+=fz; *(poff++) = sxy*((
unsigned int)curr - (
unsigned int)old); }
20150 cimg_forXYC(resz,x,y,c) {
20151 ptrd = resz.data(x,y,0,c);
20152 const T *
const ptrs0 = resy.data(x,y,0,c), *ptrs = ptrs0, *
const ptrsmax = ptrs0 + (_depth-2)*sxy;
20153 poff = off._data; pfoff = foff._data;
20154 cimg_forZ(resz,z) {
20155 const float t = *(pfoff++);
20157 val1 = (Tfloat)*ptrs,
20158 val0 = ptrs>ptrs0?(Tfloat)*(ptrs-sxy):val1,
20159 val2 = ptrs<=ptrsmax?(Tfloat)*(ptrs+sxy):val1,
20160 val3 = ptrs<ptrsmax?(Tfloat)*(ptrs+2*sxy):val2,
20161 val = val1 + 0.5f*(t*(-val0+val2) + t*t*(2*val0-5*val1+4*val2-val3) + t*t*t*(-val0+3*val1-3*val2+val3));
20162 *ptrd = (T)(val<vmin?vmin:val>vmax?vmax:val);
20169 }
else resz.assign(resy,
true);
20171 if (sc!=_spectrum) {
20172 if (_spectrum==1) resz.get_resize(sx,sy,sz,sc,1).move_to(resc);
20174 const float fc = (!boundary_conditions && sc>_spectrum)?(sc>1?(_spectrum-1.0f)/(sc-1):0):(float)_spectrum/sc;
20175 const unsigned int sxyz = sx*sy*sz;
20176 resc.assign(sx,sy,sz,sc);
20177 curr = old = 0; poff = off._data; pfoff = foff._data;
20178 cimg_forC(resc,c) { *(pfoff++) = curr - (
unsigned int)curr; old = curr; curr+=fc; *(poff++) = sxyz*((
unsigned int)curr - (
unsigned int)old); }
20179 cimg_forXYZ(resc,x,y,z) {
20180 ptrd = resc.data(x,y,z,0);
20181 const T *
const ptrs0 = resz.data(x,y,z,0), *ptrs = ptrs0, *
const ptrsmax = ptrs + (_spectrum-2)*sxyz;
20182 poff = off._data; pfoff = foff._data;
20183 cimg_forC(resc,c) {
20184 const float t = *(pfoff++);
20186 val1 = (Tfloat)*ptrs,
20187 val0 = ptrs>ptrs0?(Tfloat)*(ptrs-sxyz):val1,
20188 val2 = ptrs<=ptrsmax?(Tfloat)*(ptrs+sxyz):val1,
20189 val3 = ptrs<ptrsmax?(Tfloat)*(ptrs+2*sxyz):val2,
20190 val = val1 + 0.5f*(t*(-val0+val2) + t*t*(2*val0-5*val1+4*val2-val3) + t*t*t*(-val0+3*val1-3*val2+val3));
20191 *ptrd = (T)(val<vmin?vmin:val>vmax?vmax:val);
20198 }
else resc.assign(resz,
true);
20200 return resc._is_shared?(resz._is_shared?(resy._is_shared?(resx._is_shared?(+(*this)):resx):resy):resz):resc;
20209 unsigned int *poff;
20210 float *pfoff, old, curr;
20211 CImg<T> resx, resy, resz, resc;
20215 if (_width==1)
get_resize(sx,_height,_depth,_spectrum,1).move_to(resx);
20217 const float fx = (!boundary_conditions && sx>_width)?(sx>1?(_width-1.0f)/(sx-1):0):(float)_width/sx;
20218 resx.assign(sx,_height,_depth,_spectrum);
20219 curr = old = 0; poff = off._data; pfoff = foff._data;
20220 cimg_forX(resx,x) { *(pfoff++) = curr - (
unsigned int)curr; old = curr; curr+=fx; *(poff++) = (
unsigned int)curr - (
unsigned int)old; }
20222 const T *ptrs0 = _data;
20223 cimg_forYZC(resx,y,z,c) {
20224 poff = off._data; pfoff = foff._data;
20225 const T *ptrs = ptrs0, *
const ptrsmin = ptrs0 + 1, *
const ptrsmax = ptrs0 + (_width-2);
20226 cimg_forX(resx,x) {
20229 w0 = _cimg_lanczos(t+2),
20230 w1 = _cimg_lanczos(t+1),
20231 w2 = _cimg_lanczos(t),
20232 w3 = _cimg_lanczos(t-1),
20233 w4 = _cimg_lanczos(t-2);
20235 val2 = (Tfloat)*ptrs,
20236 val1 = ptrs>=ptrsmin?(Tfloat)*(ptrs-1):val2,
20237 val0 = ptrs>ptrsmin?(Tfloat)*(ptrs-2):val1,
20238 val3 = ptrs<=ptrsmax?(Tfloat)*(ptrs+1):val2,
20239 val4 = ptrs<ptrsmax?(Tfloat)*(ptrs+2):val3,
20240 val = (val0*w0 + val1*w1 + val2*w2 + val3*w3 + val4*w4)/(w1 + w2 + w3 + w4);
20241 *(ptrd++) = (T)(val<vmin?vmin:val>vmax?vmax:val);
20247 }
else resx.assign(*
this,
true);
20250 if (_height==1) resx.get_resize(sx,sy,_depth,_spectrum,1).move_to(resy);
20252 const float fy = (!boundary_conditions && sy>_height)?(sy>1?(_height-1.0f)/(sy-1):0):(float)_height/sy;
20253 resy.assign(sx,sy,_depth,_spectrum);
20254 curr = old = 0; poff = off._data; pfoff = foff._data;
20255 cimg_forY(resy,y) { *(pfoff++) = curr - (
unsigned int)curr; old = curr; curr+=fy; *(poff++) = sx*((
unsigned int)curr-(
unsigned int)old); }
20256 cimg_forXZC(resy,x,z,c) {
20257 ptrd = resy.data(x,0,z,c);
20258 const T *
const ptrs0 = resx.data(x,0,z,c), *ptrs = ptrs0, *
const ptrsmin = ptrs0 + sx, *
const ptrsmax = ptrs0 + (_height-2)*sx;
20259 poff = off._data; pfoff = foff._data;
20260 cimg_forY(resy,y) {
20263 w0 = _cimg_lanczos(t+2),
20264 w1 = _cimg_lanczos(t+1),
20265 w2 = _cimg_lanczos(t),
20266 w3 = _cimg_lanczos(t-1),
20267 w4 = _cimg_lanczos(t-2);
20269 val2 = (Tfloat)*ptrs,
20270 val1 = ptrs>=ptrsmin?(Tfloat)*(ptrs-sx):val2,
20271 val0 = ptrs>ptrsmin?(Tfloat)*(ptrs-2*sx):val1,
20272 val3 = ptrs<=ptrsmax?(Tfloat)*(ptrs+sx):val2,
20273 val4 = ptrs<ptrsmax?(Tfloat)*(ptrs+2*sx):val3,
20274 val = (val0*w0 + val1*w1 + val2*w2 + val3*w3 + val4*w4)/(w1 + w2 + w3 + w4);
20275 *ptrd = (T)(val<vmin?vmin:val>vmax?vmax:val);
20282 }
else resy.assign(resx,
true);
20285 if (_depth==1) resy.get_resize(sx,sy,sz,_spectrum,1).move_to(resz);
20287 const float fz = (!boundary_conditions && sz>_depth)?(sz>1?(_depth-1.0f)/(sz-1):0):(float)_depth/sz;
20288 const unsigned int sxy = sx*sy;
20289 resz.assign(sx,sy,sz,_spectrum);
20290 curr = old = 0; poff = off._data; pfoff = foff._data;
20291 cimg_forZ(resz,z) { *(pfoff++) = curr - (
unsigned int)curr; old = curr; curr+=fz; *(poff++) = sxy*((
unsigned int)curr - (
unsigned int)old); }
20292 cimg_forXYC(resz,x,y,c) {
20293 ptrd = resz.data(x,y,0,c);
20294 const T *
const ptrs0 = resy.data(x,y,0,c), *ptrs = ptrs0, *
const ptrsmin = ptrs0 + sxy, *
const ptrsmax = ptrs0 + (_depth-2)*sxy;
20295 poff = off._data; pfoff = foff._data;
20296 cimg_forZ(resz,z) {
20299 w0 = _cimg_lanczos(t+2),
20300 w1 = _cimg_lanczos(t+1),
20301 w2 = _cimg_lanczos(t),
20302 w3 = _cimg_lanczos(t-1),
20303 w4 = _cimg_lanczos(t-2);
20305 val2 = (Tfloat)*ptrs,
20306 val1 = ptrs>=ptrsmin?(Tfloat)*(ptrs-sxy):val2,
20307 val0 = ptrs>ptrsmin?(Tfloat)*(ptrs-2*sxy):val1,
20308 val3 = ptrs<=ptrsmax?(Tfloat)*(ptrs+sxy):val2,
20309 val4 = ptrs<ptrsmax?(Tfloat)*(ptrs+2*sxy):val3,
20310 val = (val0*w0 + val1*w1 + val2*w2 + val3*w3 + val4*w4)/(w1 + w2 + w3 + w4);
20311 *ptrd = (T)(val<vmin?vmin:val>vmax?vmax:val);
20318 }
else resz.assign(resy,
true);
20320 if (sc!=_spectrum) {
20321 if (_spectrum==1) resz.get_resize(sx,sy,sz,sc,1).move_to(resc);
20323 const float fc = (!boundary_conditions && sc>_spectrum)?(sc>1?(_spectrum-1.0f)/(sc-1):0):(float)_spectrum/sc;
20324 const unsigned int sxyz = sx*sy*sz;
20325 resc.assign(sx,sy,sz,sc);
20326 curr = old = 0; poff = off._data; pfoff = foff._data;
20327 cimg_forC(resc,c) { *(pfoff++) = curr - (
unsigned int)curr; old = curr; curr+=fc; *(poff++) = sxyz*((
unsigned int)curr - (
unsigned int)old); }
20328 cimg_forXYZ(resc,x,y,z) {
20329 ptrd = resc.data(x,y,z,0);
20330 const T *
const ptrs0 = resz.data(x,y,z,0), *ptrs = ptrs0, *
const ptrsmin = ptrs0 + sxyz, *
const ptrsmax = ptrs + (_spectrum-2)*sxyz;
20331 poff = off._data; pfoff = foff._data;
20332 cimg_forC(resc,c) {
20335 w0 = _cimg_lanczos(t+2),
20336 w1 = _cimg_lanczos(t+1),
20337 w2 = _cimg_lanczos(t),
20338 w3 = _cimg_lanczos(t-1),
20339 w4 = _cimg_lanczos(t-2);
20341 val2 = (Tfloat)*ptrs,
20342 val1 = ptrs>=ptrsmin?(Tfloat)*(ptrs-sxyz):val2,
20343 val0 = ptrs>ptrsmin?(Tfloat)*(ptrs-2*sxyz):val1,
20344 val3 = ptrs<=ptrsmax?(Tfloat)*(ptrs+sxyz):val2,
20345 val4 = ptrs<ptrsmax?(Tfloat)*(ptrs+2*sxyz):val3,
20346 val = (val0*w0 + val1*w1 + val2*w2 + val3*w3 + val4*w4)/(w1 + w2 + w3 + w4);
20347 *ptrd = (T)(val<vmin?vmin:val>vmax?vmax:val);
20354 }
else resc.assign(resz,
true);
20356 return resc._is_shared?(resz._is_shared?(resy._is_shared?(resx._is_shared?(+(*this)):resx):resy):resz):resc;
20363 "resize(): Invalid specified interpolation %d "
20364 "(should be { -1=raw | 0=none | 1=nearest | 2=average | 3=linear | 4=grid | 5=bicubic | 6=lanczos }).",
20366 interpolation_type);
20381 template<
typename t>
20383 const int interpolation_type=1,
const unsigned int boundary_conditions=0,
20384 const float centering_x = 0,
const float centering_y = 0,
20385 const float centering_z = 0,
const float centering_c = 0) {
20386 return resize(src._width,src._height,src._depth,src._spectrum,interpolation_type,boundary_conditions,
20387 centering_x,centering_y,centering_z,centering_c);
20391 template<
typename t>
20393 const int interpolation_type=1,
const unsigned int boundary_conditions=0,
20394 const float centering_x = 0,
const float centering_y = 0,
20395 const float centering_z = 0,
const float centering_c = 0)
const {
20396 return get_resize(src._width,src._height,src._depth,src._spectrum,interpolation_type,boundary_conditions,
20397 centering_x,centering_y,centering_z,centering_c);
20411 const int interpolation_type=1,
const unsigned int boundary_conditions=0,
20412 const float centering_x = 0,
const float centering_y = 0,
20413 const float centering_z = 0,
const float centering_c = 0) {
20414 return resize(disp.
width(),disp.
height(),_depth,_spectrum,interpolation_type,boundary_conditions,
20415 centering_x,centering_y,centering_z,centering_c);
20420 const int interpolation_type=1,
const unsigned int boundary_conditions=0,
20421 const float centering_x = 0,
const float centering_y = 0,
20422 const float centering_z = 0,
const float centering_c = 0)
const {
20423 return get_resize(disp.
width(),disp.
height(),_depth,_spectrum,interpolation_type,boundary_conditions,
20424 centering_x,centering_y,centering_z,centering_c);
20435 const Tfloat mask[9] = { 0.07842776544f, 0.1231940459f, 0.07842776544f,
20436 0.1231940459f, 0.1935127547f, 0.1231940459f,
20437 0.07842776544f, 0.1231940459f, 0.07842776544f };
20439 CImg<T> res(_width/2,_height/2,_depth,_spectrum);
20440 T *ptrd = res._data;
20441 cimg_forZC(*
this,z,c) cimg_for3x3(*
this,x,y,z,c,I,T)
20442 if (x%2 && y%2) *(ptrd++) = (T)
20443 (I[0]*mask[0] + I[1]*mask[1] + I[2]*mask[2] +
20444 I[3]*mask[3] + I[4]*mask[4] + I[5]*mask[5] +
20445 I[6]*mask[6] + I[7]*mask[7] + I[8]*mask[8]);
20459 #define _cimg_gs2x_for3(bound,i) \
20460 for (int i = 0, _p1##i = 0, \
20461 _n1##i = 1>=(bound)?(int)(bound)-1:1; \
20462 _n1##i<(int)(bound) || i==--_n1##i; \
20463 _p1##i = i++, ++_n1##i, ptrd1+=(res)._width, ptrd2+=(res)._width)
20465 #define _cimg_gs2x_for3x3(img,x,y,z,c,I,T) \
20466 _cimg_gs2x_for3((img)._height,y) for (int x = 0, \
20469 (I[1] = (T)(img)(_p1##x,_p1##y,z,c)), \
20470 (I[3] = I[4] = (T)(img)(0,y,z,c)), \
20471 (I[7] = (T)(img)(0,_n1##y,z,c)), \
20472 1>=(img)._width?(img).width()-1:1); \
20473 (_n1##x<(img).width() && ( \
20474 (I[2] = (T)(img)(_n1##x,_p1##y,z,c)), \
20475 (I[5] = (T)(img)(_n1##x,y,z,c)), \
20476 (I[8] = (T)(img)(_n1##x,_n1##y,z,c)),1)) || \
20479 I[3] = I[4], I[4] = I[5], \
20481 _p1##x = x++, ++_n1##x)
20484 CImg<T> res(_width<<1,_height<<1,_depth,_spectrum);
20486 cimg_forZC(*
this,z,c) {
20488 *ptrd1 = res.data(0,0,z,c),
20489 *ptrd2 = ptrd1 + res._width;
20490 _cimg_gs2x_for3x3(*
this,x,y,z,c,I,T) {
20491 if (Icp!=Icn && Ipc!=Inc) {
20492 *(ptrd1++) = Ipc==Icp?Ipc:Icc;
20493 *(ptrd1++) = Icp==Inc?Inc:Icc;
20494 *(ptrd2++) = Ipc==Icn?Ipc:Icc;
20495 *(ptrd2++) = Icn==Inc?Inc:Icc;
20496 }
else { *(ptrd1++) = Icc; *(ptrd1++) = Icc; *(ptrd2++) = Icc; *(ptrd2++) = Icc; }
20512 #define _cimg_gs3x_for3(bound,i) \
20513 for (int i = 0, _p1##i = 0, \
20514 _n1##i = 1>=(bound)?(int)(bound)-1:1; \
20515 _n1##i<(int)(bound) || i==--_n1##i; \
20516 _p1##i = i++, ++_n1##i, ptrd1+=2*(res)._width, ptrd2+=2*(res)._width, ptrd3+=2*(res)._width)
20518 #define _cimg_gs3x_for3x3(img,x,y,z,c,I,T) \
20519 _cimg_gs3x_for3((img)._height,y) for (int x = 0, \
20522 (I[0] = I[1] = (T)(img)(_p1##x,_p1##y,z,c)), \
20523 (I[3] = I[4] = (T)(img)(0,y,z,c)), \
20524 (I[6] = I[7] = (T)(img)(0,_n1##y,z,c)), \
20525 1>=(img)._width?(img).width()-1:1); \
20526 (_n1##x<(img).width() && ( \
20527 (I[2] = (T)(img)(_n1##x,_p1##y,z,c)), \
20528 (I[5] = (T)(img)(_n1##x,y,z,c)), \
20529 (I[8] = (T)(img)(_n1##x,_n1##y,z,c)),1)) || \
20531 I[0] = I[1], I[1] = I[2], \
20532 I[3] = I[4], I[4] = I[5], \
20533 I[6] = I[7], I[7] = I[8], \
20534 _p1##x = x++, ++_n1##x)
20537 CImg<T> res(3*_width,3*_height,_depth,_spectrum);
20539 cimg_forZC(*
this,z,c) {
20541 *ptrd1 = res.data(0,0,z,c),
20542 *ptrd2 = ptrd1 + res._width,
20543 *ptrd3 = ptrd2 + res._width;
20544 _cimg_gs3x_for3x3(*
this,x,y,z,c,I,T) {
20545 if (Icp != Icn && Ipc != Inc) {
20546 *(ptrd1++) = Ipc==Icp?Ipc:Icc;
20547 *(ptrd1++) = (Ipc==Icp && Icc!=Inp) || (Icp==Inc && Icc!=Ipp)?Icp:Icc;
20548 *(ptrd1++) = Icp==Inc?Inc:Icc;
20549 *(ptrd2++) = (Ipc==Icp && Icc!=Ipn) || (Ipc==Icn && Icc!=Ipp)?Ipc:Icc;
20551 *(ptrd2++) = (Icp==Inc && Icc!=Inn) || (Icn==Inc && Icc!=Inp)?Inc:Icc;
20552 *(ptrd3++) = Ipc==Icn?Ipc:Icc;
20553 *(ptrd3++) = (Ipc==Icn && Icc!=Inn) || (Icn==Inc && Icc!=Ipn)?Icn:Icc;
20554 *(ptrd3++) = Icn==Inc?Inc:Icc;
20556 *(ptrd1++) = Icc; *(ptrd1++) = Icc; *(ptrd1++) = Icc;
20557 *(ptrd2++) = Icc; *(ptrd2++) = Icc; *(ptrd2++) = Icc;
20558 *(ptrd3++) = Icc; *(ptrd3++) = Icc; *(ptrd3++) = Icc;
20571 T *pf, *pb, *buf = 0;
20574 pf = _data; pb =
data(_width-1);
20575 const unsigned int width2 = _width/2;
20576 for (
unsigned int yzv = 0; yzv<_height*_depth*_spectrum; ++yzv) {
20577 for (
unsigned int x = 0; x<width2; ++x) {
const T val = *pf; *(pf++) = *pb; *(pb--) = val; }
20578 pf+=_width - width2;
20579 pb+=_width + width2;
20583 buf =
new T[_width];
20584 pf = _data; pb =
data(0,_height-1);
20585 const unsigned int height2 = _height/2;
20586 for (
unsigned int zv = 0; zv<_depth*_spectrum; ++zv) {
20587 for (
unsigned int y = 0; y<height2; ++y) {
20588 std::memcpy(buf,pf,_width*
sizeof(T));
20589 std::memcpy(pf,pb,_width*
sizeof(T));
20590 std::memcpy(pb,buf,_width*
sizeof(T));
20594 pf+=(
unsigned long)_width*(_height - height2);
20595 pb+=(
unsigned long)_width*(_height + height2);
20599 buf =
new T[(
unsigned long)_width*_height];
20600 pf = _data; pb =
data(0,0,_depth-1);
20601 const unsigned int depth2 = _depth/2;
20602 cimg_forC(*
this,c) {
20603 for (
unsigned int z = 0; z<depth2; ++z) {
20604 std::memcpy(buf,pf,_width*_height*
sizeof(T));
20605 std::memcpy(pf,pb,_width*_height*
sizeof(T));
20606 std::memcpy(pb,buf,_width*_height*
sizeof(T));
20607 pf+=(
unsigned long)_width*_height;
20608 pb-=(
unsigned long)_width*_height;
20610 pf+=(
unsigned long)_width*_height*(_depth - depth2);
20611 pb+=(
unsigned long)_width*_height*(_depth + depth2);
20615 buf =
new T[(
unsigned long)_width*_height*_depth];
20616 pf = _data; pb =
data(0,0,0,_spectrum-1);
20617 const unsigned int _spectrum2 = _spectrum/2;
20618 for (
unsigned int v = 0; v<_spectrum2; ++v) {
20619 std::memcpy(buf,pf,_width*_height*_depth*
sizeof(T));
20620 std::memcpy(pf,pb,_width*_height*_depth*
sizeof(T));
20621 std::memcpy(pb,buf,_width*_height*_depth*
sizeof(T));
20622 pf+=(
unsigned long)_width*_height*_depth;
20623 pb-=(
unsigned long)_width*_height*_depth;
20628 "mirror(): Invalid specified axis '%c'.",
20638 return (+*
this).
mirror(axis);
20647 for (
const char *s = axes; *s; s++)
mirror(*s);
20653 return (+*
this).
mirror(axes);
20669 CImg<T>&
shift(
const int delta_x,
const int delta_y=0,
const int delta_z=0,
const int delta_c=0,
20670 const int boundary_conditions=0) {
20673 switch (boundary_conditions) {
20676 if (delta_x<0) cimg_forYZC(*
this,y,z,c) {
20677 std::memmove(
data(0,y,z,c),
data(-delta_x,y,z,c),(_width+delta_x)*
sizeof(T));
20678 std::memset(
data(_width+delta_x,y,z,c),0,-delta_x*
sizeof(T));
20679 }
else cimg_forYZC(*
this,y,z,c) {
20680 std::memmove(
data(delta_x,y,z,c),
data(0,y,z,c),(_width-delta_x)*
sizeof(T));
20681 std::memset(
data(0,y,z,c),0,delta_x*
sizeof(T));
20686 const int ndelta_x = (-delta_x>=
width())?
width()-1:-delta_x;
20687 if (!ndelta_x)
return *
this;
20688 cimg_forYZC(*
this,y,z,c) {
20689 std::memmove(
data(0,y,z,c),
data(ndelta_x,y,z,c),(_width-ndelta_x)*
sizeof(T));
20690 T *ptrd =
data(_width-1,y,z,c);
20691 const T val = *ptrd;
20692 for (
int l = 0; l<ndelta_x-1; ++l) *(--ptrd) = val;
20695 const int ndelta_x = (delta_x>=
width())?
width()-1:delta_x;
20696 if (!ndelta_x)
return *
this;
20697 cimg_forYZC(*
this,y,z,c) {
20698 std::memmove(
data(ndelta_x,y,z,c),
data(0,y,z,c),(_width-ndelta_x)*
sizeof(T));
20699 T *ptrd =
data(0,y,z,c);
20700 const T val = *ptrd;
20701 for (
int l = 0; l<ndelta_x-1; ++l) *(++ptrd) = val;
20707 if (!ndelta_x)
return *
this;
20708 T *
const buf =
new T[
cimg::abs(ndelta_x)];
20709 if (ndelta_x>0) cimg_forYZC(*
this,y,z,c) {
20710 std::memcpy(buf,
data(0,y,z,c),ndelta_x*
sizeof(T));
20711 std::memmove(
data(0,y,z,c),
data(ndelta_x,y,z,c),(_width-ndelta_x)*
sizeof(T));
20712 std::memcpy(
data(_width-ndelta_x,y,z,c),buf,ndelta_x*
sizeof(T));
20713 }
else cimg_forYZC(*
this,y,z,c) {
20714 std::memcpy(buf,
data(_width+ndelta_x,y,z,c),-ndelta_x*
sizeof(T));
20715 std::memmove(
data(-ndelta_x,y,z,c),
data(0,y,z,c),(_width+ndelta_x)*
sizeof(T));
20716 std::memcpy(
data(0,y,z,c),buf,-ndelta_x*
sizeof(T));
20723 switch (boundary_conditions) {
20726 if (delta_y<0) cimg_forZC(*
this,z,c) {
20727 std::memmove(
data(0,0,z,c),
data(0,-delta_y,z,c),_width*(_height+delta_y)*
sizeof(T));
20728 std::memset(
data(0,_height+delta_y,z,c),0,-delta_y*_width*
sizeof(T));
20729 }
else cimg_forZC(*
this,z,c) {
20730 std::memmove(
data(0,delta_y,z,c),
data(0,0,z,c),_width*(_height-delta_y)*
sizeof(T));
20731 std::memset(
data(0,0,z,c),0,delta_y*_width*
sizeof(T));
20736 const int ndelta_y = (-delta_y>=
height())?
height()-1:-delta_y;
20737 if (!ndelta_y)
return *
this;
20738 cimg_forZC(*
this,z,c) {
20739 std::memmove(
data(0,0,z,c),
data(0,ndelta_y,z,c),_width*(_height-ndelta_y)*
sizeof(T));
20740 T *ptrd =
data(0,_height-ndelta_y,z,c), *ptrs =
data(0,_height-1,z,c);
20741 for (
int l = 0; l<ndelta_y-1; ++l) { std::memcpy(ptrd,ptrs,_width*
sizeof(T)); ptrd+=_width; }
20744 const int ndelta_y = (delta_y>=
height())?
height()-1:delta_y;
20745 if (!ndelta_y)
return *
this;
20746 cimg_forZC(*
this,z,c) {
20747 std::memmove(
data(0,ndelta_y,z,c),
data(0,0,z,c),_width*(_height-ndelta_y)*
sizeof(T));
20748 T *ptrd =
data(0,1,z,c), *ptrs =
data(0,0,z,c);
20749 for (
int l = 0; l<ndelta_y-1; ++l) { std::memcpy(ptrd,ptrs,_width*
sizeof(T)); ptrd+=_width; }
20755 if (!ndelta_y)
return *
this;
20756 T *
const buf =
new T[(
unsigned long)_width*
cimg::abs(ndelta_y)];
20757 if (ndelta_y>0) cimg_forZC(*
this,z,c) {
20758 std::memcpy(buf,
data(0,0,z,c),_width*ndelta_y*
sizeof(T));
20759 std::memmove(
data(0,0,z,c),
data(0,ndelta_y,z,c),_width*(_height-ndelta_y)*
sizeof(T));
20760 std::memcpy(
data(0,_height-ndelta_y,z,c),buf,_width*ndelta_y*
sizeof(T));
20761 }
else cimg_forZC(*
this,z,c) {
20762 std::memcpy(buf,
data(0,_height+ndelta_y,z,c),-ndelta_y*_width*
sizeof(T));
20763 std::memmove(
data(0,-ndelta_y,z,c),
data(0,0,z,c),_width*(_height+ndelta_y)*
sizeof(T));
20764 std::memcpy(
data(0,0,z,c),buf,-ndelta_y*_width*
sizeof(T));
20771 switch (boundary_conditions) {
20774 if (delta_z<0) cimg_forC(*
this,c) {
20775 std::memmove(
data(0,0,0,c),
data(0,0,-delta_z,c),_width*_height*(_depth+delta_z)*
sizeof(T));
20776 std::memset(
data(0,0,_depth+delta_z,c),0,_width*_height*(-delta_z)*
sizeof(T));
20777 }
else cimg_forC(*
this,c) {
20778 std::memmove(
data(0,0,delta_z,c),
data(0,0,0,c),_width*_height*(_depth-delta_z)*
sizeof(T));
20779 std::memset(
data(0,0,0,c),0,delta_z*_width*_height*
sizeof(T));
20784 const int ndelta_z = (-delta_z>=
depth())?
depth()-1:-delta_z;
20785 if (!ndelta_z)
return *
this;
20786 cimg_forC(*
this,c) {
20787 std::memmove(
data(0,0,0,c),
data(0,0,ndelta_z,c),_width*_height*(_depth-ndelta_z)*
sizeof(T));
20788 T *ptrd =
data(0,0,_depth-ndelta_z,c), *ptrs =
data(0,0,_depth-1,c);
20789 for (
int l = 0; l<ndelta_z-1; ++l) { std::memcpy(ptrd,ptrs,_width*_height*
sizeof(T)); ptrd+=(
unsigned long)_width*_height; }
20792 const int ndelta_z = (delta_z>=
depth())?
depth()-1:delta_z;
20793 if (!ndelta_z)
return *
this;
20794 cimg_forC(*
this,c) {
20795 std::memmove(
data(0,0,ndelta_z,c),
data(0,0,0,c),_width*_height*(_depth-ndelta_z)*
sizeof(T));
20796 T *ptrd =
data(0,0,1,c), *ptrs =
data(0,0,0,c);
20797 for (
int l = 0; l<ndelta_z-1; ++l) { std::memcpy(ptrd,ptrs,_width*_height*
sizeof(T)); ptrd+=(
unsigned long)_width*_height; }
20803 if (!ndelta_z)
return *
this;
20804 T *
const buf =
new T[(
unsigned long)_width*_height*
cimg::abs(ndelta_z)];
20805 if (ndelta_z>0) cimg_forC(*
this,c) {
20806 std::memcpy(buf,
data(0,0,0,c),_width*_height*ndelta_z*
sizeof(T));
20807 std::memmove(
data(0,0,0,c),
data(0,0,ndelta_z,c),_width*_height*(_depth-ndelta_z)*
sizeof(T));
20808 std::memcpy(
data(0,0,_depth-ndelta_z,c),buf,_width*_height*ndelta_z*
sizeof(T));
20809 }
else cimg_forC(*
this,c) {
20810 std::memcpy(buf,
data(0,0,_depth+ndelta_z,c),-ndelta_z*_width*_height*
sizeof(T));
20811 std::memmove(
data(0,0,-ndelta_z,c),
data(0,0,0,c),_width*_height*(_depth+ndelta_z)*
sizeof(T));
20812 std::memcpy(
data(0,0,0,c),buf,-ndelta_z*_width*_height*
sizeof(T));
20819 switch (boundary_conditions) {
20823 std::memmove(_data,
data(0,0,0,-delta_c),_width*_height*_depth*(_spectrum+delta_c)*
sizeof(T));
20824 std::memset(
data(0,0,0,_spectrum+delta_c),0,_width*_height*_depth*(-delta_c)*
sizeof(T));
20826 std::memmove(
data(0,0,0,delta_c),_data,_width*_height*_depth*(_spectrum-delta_c)*
sizeof(T));
20827 std::memset(_data,0,delta_c*_width*_height*_depth*
sizeof(T));
20833 if (!ndelta_c)
return *
this;
20834 std::memmove(_data,
data(0,0,0,ndelta_c),_width*_height*_depth*(_spectrum-ndelta_c)*
sizeof(T));
20835 T *ptrd =
data(0,0,0,_spectrum-ndelta_c), *ptrs =
data(0,0,0,_spectrum-1);
20836 for (
int l = 0; l<ndelta_c-1; ++l) { std::memcpy(ptrd,ptrs,_width*_height*_depth*
sizeof(T)); ptrd+=(
unsigned long)_width*_height*_depth; }
20839 if (!ndelta_c)
return *
this;
20840 std::memmove(
data(0,0,0,ndelta_c),_data,_width*_height*_depth*(_spectrum-ndelta_c)*
sizeof(T));
20841 T *ptrd =
data(0,0,0,1);
20842 for (
int l = 0; l<ndelta_c-1; ++l) { std::memcpy(ptrd,_data,_width*_height*_depth*
sizeof(T)); ptrd+=(
unsigned long)_width*_height*_depth; }
20847 if (!ndelta_c)
return *
this;
20848 T *
const buf =
new T[(
unsigned long)_width*_height*_depth*
cimg::abs(ndelta_c)];
20850 std::memcpy(buf,_data,_width*_height*_depth*ndelta_c*
sizeof(T));
20851 std::memmove(_data,
data(0,0,0,ndelta_c),_width*_height*_depth*(_spectrum-ndelta_c)*
sizeof(T));
20852 std::memcpy(
data(0,0,0,_spectrum-ndelta_c),buf,_width*_height*_depth*ndelta_c*
sizeof(T));
20854 std::memcpy(buf,
data(0,0,0,_spectrum+ndelta_c),-ndelta_c*_width*_height*_depth*
sizeof(T));
20855 std::memmove(
data(0,0,0,-ndelta_c),_data,_width*_height*_depth*(_spectrum+ndelta_c)*
sizeof(T));
20856 std::memcpy(_data,buf,-ndelta_c*_width*_height*_depth*
sizeof(T));
20865 CImg<T> get_shift(
const int delta_x,
const int delta_y=0,
const int delta_z=0,
const int delta_c=0,
20866 const int boundary_conditions=0)
const {
20867 return (+*
this).shift(delta_x,delta_y,delta_z,delta_c,boundary_conditions);
20881 const T foo = (T)0;
20882 return _get_permute_axes(order,foo);
20885 template<
typename t>
20886 CImg<t> _get_permute_axes(
const char *
const permut,
const t&)
const {
20889 const T* ptrs = _data;
20892 res.assign(_width,_height,_spectrum,_depth);
20893 const unsigned long wh = (
unsigned long)res._width*res._height, whd = wh*res._depth;
20894 cimg_forXYZC(*
this,x,y,z,c) res(x,y,c,z,wh,whd) = (t)*(ptrs++);
20897 res.assign(_width,_depth,_height,_spectrum);
20898 const unsigned long wh = (
unsigned long)res._width*res._height, whd = wh*res._depth;
20899 cimg_forXYZC(*
this,x,y,z,c) res(x,z,y,c,wh,whd) = (t)*(ptrs++);
20902 res.assign(_width,_depth,_spectrum,_height);
20903 const unsigned long wh = (
unsigned long)res._width*res._height, whd = wh*res._depth;
20904 cimg_forXYZC(*
this,x,y,z,c) res(x,z,c,y,wh,whd) = (t)*(ptrs++);
20907 res.assign(_width,_spectrum,_height,_depth);
20908 const unsigned long wh = (
unsigned long)res._width*res._height, whd = wh*res._depth;
20909 cimg_forXYZC(*
this,x,y,z,c) res(x,c,y,z,wh,whd) = (t)*(ptrs++);
20912 res.assign(_width,_spectrum,_depth,_height);
20913 const unsigned long wh = (
unsigned long)res._width*res._height, whd = wh*res._depth;
20914 cimg_forXYZC(*
this,x,y,z,c) res(x,c,z,y,wh,whd) = (t)*(ptrs++);
20917 res.assign(_height,_width,_depth,_spectrum);
20918 const unsigned long wh = (
unsigned long)res._width*res._height, whd = wh*res._depth;
20919 cimg_forXYZC(*
this,x,y,z,c) res(y,x,z,c,wh,whd) = (t)*(ptrs++);
20922 res.assign(_height,_width,_spectrum,_depth);
20923 const unsigned long wh = (
unsigned long)res._width*res._height, whd = wh*res._depth;
20924 cimg_forXYZC(*
this,x,y,z,c) res(y,x,c,z,wh,whd) = (t)*(ptrs++);
20927 res.assign(_height,_depth,_width,_spectrum);
20928 const unsigned long wh = (
unsigned long)res._width*res._height, whd = wh*res._depth;
20929 cimg_forXYZC(*
this,x,y,z,c) res(y,z,x,c,wh,whd) = (t)*(ptrs++);
20932 res.assign(_height,_depth,_spectrum,_width);
20935 t *ptr_r = res.data(0,0,0,0);
20936 for (
unsigned int siz = _height*_depth*_spectrum; siz; --siz) {
20937 *(ptr_r++) = (t)*(ptrs++);
20941 t *ptr_r = res.data(0,0,0,0), *ptr_g = res.data(0,0,0,1);
20942 for (
unsigned int siz = _height*_depth*_spectrum; siz; --siz) {
20943 *(ptr_r++) = (t)*(ptrs++); *(ptr_g++) = (t)*(ptrs++);
20947 t *ptr_r = res.data(0,0,0,0), *ptr_g = res.data(0,0,0,1), *ptr_b = res.data(0,0,0,2);
20948 for (
unsigned int siz = _height*_depth*_spectrum; siz; --siz) {
20949 *(ptr_r++) = (t)*(ptrs++); *(ptr_g++) = (t)*(ptrs++); *(ptr_b++) = (t)*(ptrs++);
20953 t *ptr_r = res.data(0,0,0,0), *ptr_g = res.data(0,0,0,1), *ptr_b = res.data(0,0,0,2), *ptr_a = res.data(0,0,0,3);
20954 for (
unsigned int siz = _height*_depth*_spectrum; siz; --siz) {
20955 *(ptr_r++) = (t)*(ptrs++); *(ptr_g++) = (t)*(ptrs++); *(ptr_b++) = (t)*(ptrs++); *(ptr_a++) = (t)*(ptrs++);
20959 const unsigned long wh = (
unsigned long)res._width*res._height, whd = wh*res._depth;
20960 cimg_forXYZC(*
this,x,y,z,c) res(y,z,c,x,wh,whd) = *(ptrs++);
20966 res.assign(_height,_spectrum,_width,_depth);
20967 const unsigned long wh = (
unsigned long)res._width*res._height, whd = wh*res._depth;
20968 cimg_forXYZC(*
this,x,y,z,c) res(y,c,x,z,wh,whd) = (t)*(ptrs++);
20971 res.assign(_height,_spectrum,_depth,_width);
20972 const unsigned long wh = (
unsigned long)res._width*res._height, whd = wh*res._depth;
20973 cimg_forXYZC(*
this,x,y,z,c) res(y,c,z,x,wh,whd) = (t)*(ptrs++);
20976 res.assign(_depth,_width,_height,_spectrum);
20977 const unsigned long wh = (
unsigned long)res._width*res._height, whd = wh*res._depth;
20978 cimg_forXYZC(*
this,x,y,z,c) res(z,x,y,c,wh,whd) = (t)*(ptrs++);
20981 res.assign(_depth,_width,_spectrum,_height);
20982 const unsigned long wh = (
unsigned long)res._width*res._height, whd = wh*res._depth;
20983 cimg_forXYZC(*
this,x,y,z,c) res(z,x,c,y,wh,whd) = (t)*(ptrs++);
20986 res.assign(_depth,_height,_width,_spectrum);
20987 const unsigned long wh = (
unsigned long)res._width*res._height, whd = wh*res._depth;
20988 cimg_forXYZC(*
this,x,y,z,c) res(z,y,x,c,wh,whd) = (t)*(ptrs++);
20991 res.assign(_depth,_height,_spectrum,_width);
20992 const unsigned long wh = (
unsigned long)res._width*res._height, whd = wh*res._depth;
20993 cimg_forXYZC(*
this,x,y,z,c) res(z,y,c,x,wh,whd) = (t)*(ptrs++);
20996 res.assign(_depth,_spectrum,_width,_height);
20997 const unsigned long wh = (
unsigned long)res._width*res._height, whd = wh*res._depth;
20998 cimg_forXYZC(*
this,x,y,z,c) res(z,c,x,y,wh,whd) = (t)*(ptrs++);
21001 res.assign(_depth,_spectrum,_height,_width);
21002 const unsigned long wh = (
unsigned long)res._width*res._height, whd = wh*res._depth;
21003 cimg_forXYZC(*
this,x,y,z,c) res(z,c,y,x,wh,whd) = (t)*(ptrs++);
21006 res.assign(_spectrum,_width,_height,_depth);
21007 switch (_spectrum) {
21009 const T *ptr_r =
data(0,0,0,0);
21010 t *ptrd = res._data;
21011 for (
unsigned long siz = (
unsigned long)_width*_height*_depth; siz; --siz) *(ptrd++) = (t)*(ptr_r++);
21014 const T *ptr_r =
data(0,0,0,0), *ptr_g =
data(0,0,0,1);
21015 t *ptrd = res._data;
21016 for (
unsigned long siz = (
unsigned long)_width*_height*_depth; siz; --siz) {
21017 *(ptrd++) = (t)*(ptr_r++); *(ptrd++) = (t)*(ptr_g++);
21021 const T *ptr_r =
data(0,0,0,0), *ptr_g =
data(0,0,0,1), *ptr_b =
data(0,0,0,2);
21022 t *ptrd = res._data;
21023 for (
unsigned long siz = (
unsigned long)_width*_height*_depth; siz; --siz) {
21024 *(ptrd++) = (t)*(ptr_r++); *(ptrd++) = (t)*(ptr_g++); *(ptrd++) = (t)*(ptr_b++);
21028 const T *ptr_r =
data(0,0,0,0), *ptr_g =
data(0,0,0,1), *ptr_b =
data(0,0,0,2), *ptr_a =
data(0,0,0,3);
21029 t *ptrd = res._data;
21030 for (
unsigned long siz = (
unsigned long)_width*_height*_depth; siz; --siz) {
21031 *(ptrd++) = (t)*(ptr_r++); *(ptrd++) = (t)*(ptr_g++); *(ptrd++) = (t)*(ptr_b++); *(ptrd++) = (t)*(ptr_a++);
21035 const unsigned long wh = (
unsigned long)res._width*res._height, whd = wh*res._depth;
21036 cimg_forXYZC(*
this,x,y,z,c) res(c,x,y,z,wh,whd) = (t)*(ptrs++);
21041 res.assign(_spectrum,_width,_depth,_height);
21042 const unsigned long wh = (
unsigned long)res._width*res._height, whd = wh*res._depth;
21043 cimg_forXYZC(*
this,x,y,z,c) res(c,x,z,y,wh,whd) = (t)*(ptrs++);
21046 res.assign(_spectrum,_height,_width,_depth);
21047 const unsigned long wh = (
unsigned long)res._width*res._height, whd = wh*res._depth;
21048 cimg_forXYZC(*
this,x,y,z,c) res(c,y,x,z,wh,whd) = (t)*(ptrs++);
21051 res.assign(_spectrum,_height,_depth,_width);
21052 const unsigned long wh = (
unsigned long)res._width*res._height, whd = wh*res._depth;
21053 cimg_forXYZC(*
this,x,y,z,c) res(c,y,z,x,wh,whd) = (t)*(ptrs++);
21056 res.assign(_spectrum,_depth,_width,_height);
21057 const unsigned long wh = (
unsigned long)res._width*res._height, whd = wh*res._depth;
21058 cimg_forXYZC(*
this,x,y,z,c) res(c,z,x,y,wh,whd) = (t)*(ptrs++);
21061 res.assign(_spectrum,_depth,_height,_width);
21062 const unsigned long wh = (
unsigned long)res._width*res._height, whd = wh*res._depth;
21063 cimg_forXYZC(*
this,x,y,z,c) res(c,z,y,x,wh,whd) = (t)*(ptrs++);
21066 throw CImgArgumentException(_cimg_instance
21067 "permute_axes(): Invalid specified permutation '%s'.",
21078 const unsigned int siz =
size();
21079 if (siz)
switch (axis) {
21080 case 'x' : _width = siz; _height = _depth = _spectrum = 1;
break;
21081 case 'y' : _height = siz; _width = _depth = _spectrum = 1;
break;
21082 case 'z' : _depth = siz; _width = _height = _spectrum = 1;
break;
21083 default : _spectrum = siz; _width = _height = _depth = 1;
21090 return (+*
this).
unroll(axis);
21100 CImg<T>&
rotate(
const float angle,
const unsigned int boundary_conditions=0,
const unsigned int interpolation_type=1) {
21101 return get_rotate(angle,boundary_conditions,interpolation_type).move_to(*
this);
21105 CImg<T> get_rotate(
const float angle,
const unsigned int boundary_conditions=0,
const unsigned int interpolation_type=1)
const {
21108 const float nangle =
cimg::mod(angle,360.0f);
21109 if (boundary_conditions!=1 &&
cimg::mod(nangle,90.0f)==0) {
21111 const int iangle = (int)nangle/90;
21114 res.assign(_height,_width,_depth,_spectrum);
21115 T *ptrd = res._data;
21116 cimg_forXYZC(res,x,y,z,c) *(ptrd++) = (*
this)(y,hm1-x,z,c);
21119 res.assign(_width,_height,_depth,_spectrum);
21120 T *ptrd = res._data;
21121 cimg_forXYZC(res,x,y,z,c) *(ptrd++) = (*
this)(wm1-x,hm1-y,z,c);
21124 res.assign(_height,_width,_depth,_spectrum);
21125 T *ptrd = res._data;
21126 cimg_forXYZC(res,x,y,z,c) *(ptrd++) = (*
this)(wm1-y,x,z,c);
21134 rad = (float)(nangle*
cimg::PI/180.0),
21135 ca = (float)std::cos(rad),
21136 sa = (float)std::sin(rad),
21139 w2 = 0.5f*_width, h2 = 0.5f*_height,
21140 dw2 = 0.5f*(ux+vx), dh2 = 0.5f*(uy+vy);
21141 res.assign((
int)(ux+vx),(
int)(uy+vy),_depth,_spectrum);
21142 switch (boundary_conditions) {
21144 switch (interpolation_type) {
21146 cimg_forXY(res,x,y) cimg_forZC(*
this,z,c) {
21147 const Tfloat val =
cubic_atXY(w2 + (x-dw2)*ca + (y-dh2)*sa,h2 - (x-dw2)*sa + (y-dh2)*ca,z,c,0);
21148 res(x,y,z,c) = (T)(val<vmin?vmin:val>vmax?vmax:val);
21152 cimg_forXY(res,x,y) cimg_forZC(*
this,z,c)
21153 res(x,y,z,c) = (T)
linear_atXY(w2 + (x-dw2)*ca + (y-dh2)*sa,h2 - (x-dw2)*sa + (y-dh2)*ca,z,c,0);
21156 cimg_forXY(res,x,y) cimg_forZC(*
this,z,c)
21157 res(x,y,z,c) =
atXY((
int)(w2 + (x-dw2)*ca + (y-dh2)*sa),(
int)(h2 - (x-dw2)*sa + (y-dh2)*ca),z,c,0);
21162 switch (interpolation_type) {
21164 cimg_forXY(res,x,y) cimg_forZC(*
this,z,c) {
21165 const Tfloat val = _cubic_atXY(w2 + (x-dw2)*ca + (y-dh2)*sa,h2 - (x-dw2)*sa + (y-dh2)*ca,z,c);
21166 res(x,y,z,c) = (T)(val<vmin?vmin:val>vmax?vmax:val);
21170 cimg_forXY(res,x,y) cimg_forZC(*
this,z,c)
21171 res(x,y,z,c) = (T)_linear_atXY(w2 + (x-dw2)*ca + (y-dh2)*sa,h2 - (x-dw2)*sa + (y-dh2)*ca,z,c);
21174 cimg_forXY(res,x,y) cimg_forZC(*
this,z,c)
21175 res(x,y,z,c) = _atXY((
int)(w2 + (x-dw2)*ca + (y-dh2)*sa),(
int)(h2 - (x-dw2)*sa + (y-dh2)*ca),z,c);
21180 switch (interpolation_type) {
21182 cimg_forXY(res,x,y) cimg_forZC(*
this,z,c) {
21183 const Tfloat val = _cubic_atXY(
cimg::mod(w2 + (x-dw2)*ca + (y-dh2)*sa,(
float)
width()),
21185 res(x,y,z,c) = (T)(val<vmin?vmin:val>vmax?vmax:val);
21189 cimg_forXY(res,x,y) cimg_forZC(*
this,z,c)
21190 res(x,y,z,c) = (T)_linear_atXY(
cimg::mod(w2 + (x-dw2)*ca + (y-dh2)*sa,(
float)
width()),
21194 cimg_forXY(res,x,y) cimg_forZC(*
this,z,c)
21195 res(x,y,z,c) = (*this)(
cimg::mod((
int)(w2 + (x-dw2)*ca + (y-dh2)*sa),
width()),
21202 "rotate(): Invalid specified border conditions %d "
21203 "(should be { 0=dirichlet | 1=neumann | 2=cyclic }).",
21205 boundary_conditions);
21220 CImg<T>&
rotate(
const float angle,
const float cx,
const float cy,
const float zoom,
21221 const unsigned int boundary_conditions=3,
const unsigned int interpolation_type=1) {
21222 return get_rotate(angle,cx,cy,zoom,boundary_conditions,interpolation_type).move_to(*
this);
21227 const unsigned int boundary_conditions=3,
const unsigned int interpolation_type=1)
const {
21228 if (interpolation_type>2)
21230 "rotate(): Invalid specified interpolation type %d "
21231 "(should be { 0=none | 1=linear | 2=bicubic }).",
21233 interpolation_type);
21236 CImg<T> res(_width,_height,_depth,_spectrum);
21239 rad = (float)((angle*
cimg::PI)/180.0),
21240 ca = (float)std::cos(rad)/zoom,
21241 sa = (float)std::sin(rad)/zoom;
21242 switch (boundary_conditions) {
21244 switch (interpolation_type) {
21246 cimg_forXY(res,x,y) cimg_forZC(*
this,z,c) {
21247 const Tfloat val =
cubic_atXY(cx + (x-cx)*ca + (y-cy)*sa,cy - (x-cx)*sa + (y-cy)*ca,z,c,0);
21248 res(x,y,z,c) = (T)(val<vmin?vmin:val>vmax?vmax:val);
21252 cimg_forXY(res,x,y) cimg_forZC(*
this,z,c)
21253 res(x,y,z,c) = (T)
linear_atXY(cx + (x-cx)*ca + (y-cy)*sa,cy - (x-cx)*sa + (y-cy)*ca,z,c,0);
21256 cimg_forXY(res,x,y) cimg_forZC(*
this,z,c)
21257 res(x,y,z,c) =
atXY((
int)(cx + (x-cx)*ca + (y-cy)*sa),(
int)(cy - (x-cx)*sa + (y-cy)*ca),z,c,0);
21262 switch (interpolation_type) {
21264 cimg_forXY(res,x,y) cimg_forZC(*
this,z,c) {
21265 const Tfloat val = _cubic_atXY(cx + (x-cx)*ca + (y-cy)*sa,cy - (x-cx)*sa + (y-cy)*ca,z,c);
21266 res(x,y,z,c) = (T)(val<vmin?vmin:val>vmax?vmax:val);
21270 cimg_forXY(res,x,y) cimg_forZC(*
this,z,c)
21271 res(x,y,z,c) = (T)_linear_atXY(cx + (x-cx)*ca + (y-cy)*sa,cy - (x-cx)*sa + (y-cy)*ca,z,c);
21274 cimg_forXY(res,x,y) cimg_forZC(*
this,z,c)
21275 res(x,y,z,c) = _atXY((
int)(cx + (x-cx)*ca + (y-cy)*sa),(
int)(cy - (x-cx)*sa + (y-cy)*ca),z,c);
21280 switch (interpolation_type) {
21282 cimg_forXY(res,x,y) cimg_forZC(*
this,z,c) {
21283 const Tfloat val = _cubic_atXY(
cimg::mod(cx + (x-cx)*ca + (y-cy)*sa,(
float)
width()),
21285 res(x,y,z,c) = (T)(val<vmin?vmin:val>vmax?vmax:val);
21289 cimg_forXY(res,x,y) cimg_forZC(*
this,z,c)
21290 res(x,y,z,c) = (T)_linear_atXY(
cimg::mod(cx + (x-cx)*ca + (y-cy)*sa,(
float)
width()),
21294 cimg_forXY(res,x,y) cimg_forZC(*
this,z,c)
21295 res(x,y,z,c) = (*this)(
cimg::mod((
int)(cx + (x-cx)*ca + (y-cy)*sa),
width()),
21302 "rotate(): Invalid specified border conditions %d "
21303 "(should be { 0=dirichlet | 1=neumann | 2=cyclic }).",
21305 boundary_conditions);
21317 template<
typename t>
21319 const bool is_linear_interpolation=
true,
const unsigned int boundary_conditions=0) {
21320 return get_warp(warp,is_relative,is_linear_interpolation,boundary_conditions).move_to(*
this);
21324 template<
typename t>
21326 const bool is_linear_interpolation=
true,
const unsigned int boundary_conditions=0)
const {
21327 if (
is_empty() || !warp)
return *
this;
21330 "warp(): Instance and specified relative warping field (%u,%u,%u,%u,%p) "
21331 "have different XYZ dimensions.",
21333 warp._width,warp._height,warp._depth,warp._spectrum,warp._data);
21335 CImg<T> res(warp._width,warp._height,warp._depth,_spectrum);
21336 T *ptrd = res._data;
21337 switch (warp._spectrum) {
21340 if (is_linear_interpolation)
switch (boundary_conditions) {
21343 const t *ptrs0 = warp._data;
21344 cimg_forXYZ(res,x,y,z)
21345 *(ptrd++) = (T)_linear_atX(
cimg::mod(x - (
float)*(ptrs0++),(
float)_width),y,z,c);
21350 const t *ptrs0 = warp._data;
21351 cimg_forXYZ(res,x,y,z)
21352 *(ptrd++) = (T)_linear_atX(x - (
float)*(ptrs0++),y,z,c);
21357 const t *ptrs0 = warp._data;
21358 cimg_forXYZ(res,x,y,z)
21359 *(ptrd++) = (T)
linear_atX(x - (
float)*(ptrs0++),y,z,c,0);
21362 }
else switch (boundary_conditions) {
21365 const t *ptrs0 = warp._data;
21366 cimg_forXYZ(res,x,y,z)
21367 *(ptrd++) = (*
this)(
cimg::mod(x - (
int)*(ptrs0++),(
int)_width),y,z,c);
21372 const t *ptrs0 = warp._data;
21373 cimg_forXYZ(res,x,y,z)
21374 *(ptrd++) = _atX(x - (
int)*(ptrs0++),y,z,c);
21379 const t *ptrs0 = warp._data;
21380 cimg_forXYZ(res,x,y,z)
21381 *(ptrd++) =
atX(x - (
int)*(ptrs0++),y,z,c,0);
21386 if (is_linear_interpolation)
switch (boundary_conditions) {
21389 const t *ptrs0 = warp._data;
21390 cimg_forXYZ(res,x,y,z)
21391 *(ptrd++) = (T)_linear_atX(
cimg::mod((
float)*(ptrs0++),(
float)_width),0,0,c);
21396 const t *ptrs0 = warp._data;
21397 cimg_forXYZ(res,x,y,z)
21398 *(ptrd++) = (T)_linear_atX((
float)*(ptrs0++),0,0,c);
21403 const t *ptrs0 = warp._data;
21404 cimg_forXYZ(res,x,y,z)
21405 *(ptrd++) = (T)
linear_atX((
float)*(ptrs0++),0,0,c,0);
21408 }
else switch (boundary_conditions) {
21411 const t *ptrs0 = warp._data;
21412 cimg_forXYZ(res,x,y,z)
21413 *(ptrd++) = (*
this)(
cimg::mod((
int)*(ptrs0++),(
int)_width),0,0,c);
21418 const t *ptrs0 = warp._data;
21419 cimg_forXYZ(res,x,y,z)
21420 *(ptrd++) = _atX((
int)*(ptrs0++),0,0,c);
21425 const t *ptrs0 = warp._data;
21426 cimg_forXYZ(res,x,y,z)
21427 *(ptrd++) =
atX((
int)*(ptrs0++),0,0,c,0);
21436 if (is_linear_interpolation)
switch (boundary_conditions) {
21439 const t *ptrs0 = warp.data(0,0,0,0), *ptrs1 = warp.data(0,0,0,1);
21440 cimg_forXYZ(res,x,y,z)
21441 *(ptrd++) = (T)_linear_atXY(
cimg::mod(x - (
float)*(ptrs0++),(
float)_width),
21442 cimg::mod(y - (
float)*(ptrs1++),(
float)_height),z,c);
21447 const t *ptrs0 = warp.data(0,0,0,0), *ptrs1 = warp.data(0,0,0,1);
21448 cimg_forXYZ(res,x,y,z)
21449 *(ptrd++) = (T)_linear_atXY(x - (
float)*(ptrs0++),y - (
float)*(ptrs1++),z,c);
21454 const t *ptrs0 = warp.data(0,0,0,0), *ptrs1 = warp.data(0,0,0,1);
21455 cimg_forXYZ(res,x,y,z)
21456 *(ptrd++) = (T)
linear_atXY(x - (
float)*(ptrs0++),y - (
float)*(ptrs1++),z,c,0);
21459 }
else switch (boundary_conditions) {
21462 const t *ptrs0 = warp.data(0,0,0,0), *ptrs1 = warp.data(0,0,0,1);
21463 cimg_forXYZ(res,x,y,z)
21464 *(ptrd++) = (*
this)(
cimg::mod(x - (
int)*(ptrs0++),(
int)_width),
21465 cimg::mod(y - (
int)*(ptrs1++),(
int)_height),z,c);
21470 const t *ptrs0 = warp.data(0,0,0,0), *ptrs1 = warp.data(0,0,0,1);
21471 cimg_forXYZ(res,x,y,z)
21472 *(ptrd++) = _atXY(x - (
int)*(ptrs0++),y - (
int)*(ptrs1++),z,c);
21477 const t *ptrs0 = warp.data(0,0,0,0), *ptrs1 = warp.data(0,0,0,1);
21478 cimg_forXYZ(res,x,y,z)
21479 *(ptrd++) =
atXY(x - (
int)*(ptrs0++),y - (
int)*(ptrs1++),z,c,0);
21484 if (is_linear_interpolation)
switch (boundary_conditions) {
21487 const t *ptrs0 = warp.data(0,0,0,0), *ptrs1 = warp.data(0,0,0,1);
21488 cimg_forXYZ(res,x,y,z)
21489 *(ptrd++) = (T)_linear_atXY(
cimg::mod((
float)*(ptrs0++),(
float)_width),
21490 cimg::mod((
float)*(ptrs1++),(
float)_height),0,c);
21495 const t *ptrs0 = warp.data(0,0,0,0), *ptrs1 = warp.data(0,0,0,1);
21496 cimg_forXYZ(res,x,y,z)
21497 *(ptrd++) = (T)_linear_atXY((
float)*(ptrs0++),(
float)*(ptrs1++),0,c);
21502 const t *ptrs0 = warp.data(0,0,0,0), *ptrs1 = warp.data(0,0,0,1);
21503 cimg_forXYZ(res,x,y,z)
21504 *(ptrd++) = (T)
linear_atXY((
float)*(ptrs0++),(
float)*(ptrs1++),0,c,0);
21507 }
else switch (boundary_conditions) {
21510 const t *ptrs0 = warp.data(0,0,0,0), *ptrs1 = warp.data(0,0,0,1);
21511 cimg_forXYZ(res,x,y,z)
21512 *(ptrd++) = (*
this)(
cimg::mod((
int)*(ptrs0++),(
int)_width),
21513 cimg::mod((
int)*(ptrs1++),(
int)_height),0,c);
21518 const t *ptrs0 = warp.data(0,0,0,0), *ptrs1 = warp.data(0,0,0,1);
21519 cimg_forXYZ(res,x,y,z)
21520 *(ptrd++) = _atXY((
int)*(ptrs0++),(
int)*(ptrs1++),0,c);
21525 const t *ptrs0 = warp.data(0,0,0,0), *ptrs1 = warp.data(0,0,0,1);
21526 cimg_forXYZ(res,x,y,z)
21527 *(ptrd++) =
atXY((
int)*(ptrs0++),(
int)*(ptrs1++),0,c,0);
21536 if (is_linear_interpolation)
switch (boundary_conditions) {
21539 const t *ptrs0 = warp.data(0,0,0,0), *ptrs1 = warp.data(0,0,0,1), *ptrs2 = warp.data(0,0,0,2);
21540 cimg_forXYZ(res,x,y,z)
21541 *(ptrd++) = (T)_linear_atXYZ(
cimg::mod(x - (
float)*(ptrs0++),(
float)_width),
21542 cimg::mod(y - (
float)*(ptrs1++),(
float)_height),
21543 cimg::mod(z - (
float)*(ptrs2++),(
float)_depth),c);
21548 const t *ptrs0 = warp.data(0,0,0,0), *ptrs1 = warp.data(0,0,0,1), *ptrs2 = warp.data(0,0,0,2);
21549 cimg_forXYZ(res,x,y,z)
21550 *(ptrd++) = (T)_linear_atXYZ(x - (
float)*(ptrs0++),y - (
float)*(ptrs1++),z - (
float)*(ptrs2++),c);
21555 const t *ptrs0 = warp.data(0,0,0,0), *ptrs1 = warp.data(0,0,0,1), *ptrs2 = warp.data(0,0,0,2);
21556 cimg_forXYZ(res,x,y,z)
21557 *(ptrd++) = (T)
linear_atXYZ(x - (
float)*(ptrs0++),y - (
float)*(ptrs1++),z - (
float)*(ptrs2++),c,0);
21560 }
else switch (boundary_conditions) {
21563 const t *ptrs0 = warp.data(0,0,0,0), *ptrs1 = warp.data(0,0,0,1), *ptrs2 = warp.data(0,0,0,2);
21564 cimg_forXYZ(res,x,y,z)
21565 *(ptrd++) = (*
this)(
cimg::mod(x - (
int)*(ptrs0++),(
int)_width),
21566 cimg::mod(y - (
int)*(ptrs1++),(
int)_height),
21567 cimg::mod(z - (
int)*(ptrs2++),(
int)_depth),c);
21572 const t *ptrs0 = warp.data(0,0,0,0), *ptrs1 = warp.data(0,0,0,1), *ptrs2 = warp.data(0,0,0,2);
21573 cimg_forXYZ(res,x,y,z)
21574 *(ptrd++) = _atXYZ(x - (
int)*(ptrs0++),y - (
int)*(ptrs1++),z - (
int)*(ptrs2++),c);
21579 const t *ptrs0 = warp.data(0,0,0,0), *ptrs1 = warp.data(0,0,0,1), *ptrs2 = warp.data(0,0,0,2);
21580 cimg_forXYZ(res,x,y,z)
21581 *(ptrd++) =
atXYZ(x - (
int)*(ptrs0++),y - (
int)*(ptrs1++),z - (
int)*(ptrs2++),c,0);
21586 if (is_linear_interpolation)
switch (boundary_conditions) {
21589 const t *ptrs0 = warp.data(0,0,0,0), *ptrs1 = warp.data(0,0,0,1), *ptrs2 = warp.data(0,0,0,2);
21590 cimg_forXYZ(res,x,y,z)
21591 *(ptrd++) = (T)_linear_atXYZ(
cimg::mod((
float)*(ptrs0++),(
float)_width),
21592 cimg::mod((
float)*(ptrs1++),(
float)_height),
21593 cimg::mod((
float)*(ptrs2++),(
float)_depth),c);
21598 const t *ptrs0 = warp.data(0,0,0,0), *ptrs1 = warp.data(0,0,0,1), *ptrs2 = warp.data(0,0,0,2);
21599 cimg_forXYZ(res,x,y,z)
21600 *(ptrd++) = (T)_linear_atXYZ((
float)*(ptrs0++),(
float)*(ptrs1++),(
float)*(ptrs2++),c);
21605 const t *ptrs0 = warp.data(0,0,0,0), *ptrs1 = warp.data(0,0,0,1), *ptrs2 = warp.data(0,0,0,2);
21606 cimg_forXYZ(res,x,y,z)
21607 *(ptrd++) = (T)
linear_atXYZ((
float)*(ptrs0++),(
float)*(ptrs1++),(
float)*(ptrs2++),c,0);
21610 }
else switch (boundary_conditions) {
21613 const t *ptrs0 = warp.data(0,0,0,0), *ptrs1 = warp.data(0,0,0,1), *ptrs2 = warp.data(0,0,0,2);
21614 cimg_forXYZ(res,x,y,z)
21615 *(ptrd++) = (*
this)(
cimg::mod((
int)*(ptrs0++),(
int)_width),
21616 cimg::mod((
int)*(ptrs1++),(
int)_height),
21617 cimg::mod((
int)*(ptrs2++),(
int)_depth),c);
21622 const t *ptrs0 = warp.data(0,0,0,0), *ptrs1 = warp.data(0,0,0,1), *ptrs2 = warp.data(0,0,0,2);
21623 cimg_forXYZ(res,x,y,z)
21624 *(ptrd++) = _atXYZ((
int)*(ptrs0++),(
int)*(ptrs1++),(
int)*(ptrs2++),c);
21629 const t *ptrs0 = warp.data(0,0,0,0), *ptrs1 = warp.data(0,0,0,1), *ptrs2 = warp.data(0,0,0,2);
21630 cimg_forXYZ(res,x,y,z)
21631 *(ptrd++) =
atXYZ((
int)*(ptrs0++),(
int)*(ptrs1++),(
int)*(ptrs2++),c,0);
21647 if (
is_empty() || _depth<2)
return +*
this;
21649 _x0 = (x0>=_width)?_width - 1:x0,
21650 _y0 = (y0>=_height)?_height - 1:y0,
21651 _z0 = (z0>=_depth)?_depth - 1:z0;
21653 img_xy =
get_crop(0,0,_z0,0,_width-1,_height-1,_z0,_spectrum-1),
21654 img_zy =
get_crop(_x0,0,0,0,_x0,_height-1,_depth-1,_spectrum-1).permute_axes(
"xzyc").resize(_depth,_height,1,-100,-1),
21655 img_xz =
get_crop(0,_y0,0,0,_width-1,_y0,_depth-1,_spectrum-1).resize(_width,_depth,1,-100,-1);
21656 return CImg<T>(_width + _depth,_height + _depth,1,_spectrum,
cimg::min(img_xy.min(),img_zy.min(),img_xz.min())).
21657 draw_image(0,0,img_xy).draw_image(img_xy._width,0,img_zy).
21663 if (_depth<2)
return *
this;
21680 const int x1,
const int y1,
const int z1,
const int c1,
21681 const bool boundary_conditions=
false) {
21682 return get_crop(x0,y0,z0,c0,x1,y1,z1,c1,boundary_conditions).move_to(*
this);
21687 const int x1,
const int y1,
const int z1,
const int c1,
21688 const bool boundary_conditions=
false)
const {
21691 "crop(): Empty instance.",
21694 nx0 = x0<x1?x0:x1, nx1 = x0^x1^nx0,
21695 ny0 = y0<y1?y0:y1, ny1 = y0^y1^ny0,
21696 nz0 = z0<z1?z0:z1, nz1 = z0^z1^nz0,
21697 nc0 = c0<c1?c0:c1, nc1 = c0^c1^nc0;
21698 CImg<T> res(1U + nx1 - nx0,1U + ny1 - ny0,1U + nz1 - nz0,1U + nc1 - nc0);
21700 if (boundary_conditions) cimg_forXYZC(res,x,y,z,c) res(x,y,z,c) = _atXYZC(nx0+x,ny0+y,nz0+z,nc0+c);
21701 else res.fill(0).draw_image(-nx0,-ny0,-nz0,-nc0,*
this);
21702 }
else res.draw_image(-nx0,-ny0,-nz0,-nc0,*
this);
21708 const int x1,
const int y1,
const int z1,
21709 const bool boundary_conditions=
false) {
21710 return crop(x0,y0,z0,0,x1,y1,z1,_spectrum-1,boundary_conditions);
21715 const int x1,
const int y1,
const int z1,
21716 const bool boundary_conditions=
false)
const {
21717 return get_crop(x0,y0,z0,0,x1,y1,z1,_spectrum-1,boundary_conditions);
21722 const int x1,
const int y1,
21723 const bool boundary_conditions=
false) {
21724 return crop(x0,y0,0,0,x1,y1,_depth - 1,_spectrum - 1,boundary_conditions);
21729 const int x1,
const int y1,
21730 const bool boundary_conditions=
false)
const {
21731 return get_crop(x0,y0,0,0,x1,y1,_depth - 1,_spectrum - 1,boundary_conditions);
21735 CImg<T>&
crop(
const int x0,
const int x1,
const bool boundary_conditions=
false) {
21736 return crop(x0,0,0,0,x1,_height-1,_depth-1,_spectrum-1,boundary_conditions);
21741 return get_crop(x0,0,0,0,x1,_height-1,_depth-1,_spectrum-1,boundary_conditions);
21747 for (
const char *s = axes; *s; ++s) {
21749 const CImg<intT> coords = _autocrop(value,axis);
21750 if (coords[0]==-1 && coords[1]==-1)
return assign();
21751 else switch (axis) {
21753 const int x0 = coords[0], x1 = coords[1];
21754 if (x0>=0 && x1>=0)
crop(x0,x1);
21757 const int y0 = coords[0], y1 = coords[1];
21758 if (y0>=0 && y1>=0)
crop(0,y0,_width-1,y1);
21761 const int z0 = coords[0], z1 = coords[1];
21762 if (z0>=0 && z1>=0)
crop(0,0,z0,_width-1,_height-1,z1);
21765 const int c0 = coords[0], c1 = coords[1];
21766 if (c0>=0 && c1>=0)
crop(0,0,0,c0,_width-1,_height-1,_depth-1,c1);
21775 return (+*
this).
autocrop(value,axes);
21787 const unsigned int w = _width, h = _height, d = _depth, s = _spectrum;
21789 if (_width==w && _height==h && _depth==d && _spectrum==s) {
21795 for (
const char *s = axes; *s; ++s) {
21799 int x0 =
width(), x1 = -1;
21800 cimg_forC(*
this,c) {
21802 const int nx0 = coords[0], nx1 = coords[1];
21808 int y0 =
height(), y1 = -1;
21809 cimg_forC(*
this,c) {
21811 const int ny0 = coords[0], ny1 = coords[1];
21817 int z0 =
depth(), z1 = -1;
21818 cimg_forC(*
this,c) {
21820 const int nz0 = coords[0], nz1 = coords[1];
21823 if (z0==
depth() && z1==-1)
return assign();
else crop(0,0,z0,_width-1,_height-1,z1);
21832 return (+*
this).
autocrop(color,axes);
21845 CImg<intT> _autocrop(
const T value,
const char axis)
const {
21849 int x0 = -1, x1 = -1;
21850 cimg_forX(*
this,x) cimg_forYZC(*this,y,z,c)
21853 for (
int x =
width()-1; x>=0; --x) cimg_forYZC(*
this,y,z,c)
21854 if ((*
this)(x,y,z,c)!=value) { x1 = x; x = 0; y =
height(); z =
depth(); c =
spectrum(); }
21859 int y0 = -1, y1 = -1;
21860 cimg_forY(*
this,y) cimg_forXZC(*this,x,z,c)
21863 for (
int y =
height()-1; y>=0; --y) cimg_forXZC(*
this,x,z,c)
21864 if ((*
this)(x,y,z,c)!=value) { y1 = y; x =
width(); y = 0; z =
depth(); c =
spectrum(); }
21869 int z0 = -1, z1 = -1;
21870 cimg_forZ(*
this,z) cimg_forXYC(*this,x,y,c)
21873 for (
int z =
depth()-1; z>=0; --z) cimg_forXYC(*
this,x,y,c)
21874 if ((*
this)(x,y,z,c)!=value) { z1 = z; x =
width(); y =
height(); z = 0; c =
spectrum(); }
21879 int c0 = -1, c1 = -1;
21880 cimg_forC(*
this,c) cimg_forXYZ(*this,x,y,z)
21883 for (
int c =
spectrum()-1; c>=0; --c) cimg_forXYZ(*
this,x,y,z)
21884 if ((*
this)(x,y,z,c)!=value) { c1 = c; x =
width(); y =
height(); z =
depth(); c = 0; }
21929 return rows(y0,y0);
21943 return get_rows(y0,y1).move_to(*
this);
22002 const float L=256,
const float dl=0.1f,
22003 const unsigned int interpolation_type=2,
const bool is_backward_tracking=
false,
22004 const bool is_oriented_only=
false)
const {
22005 if (_spectrum!=2 && _spectrum!=3)
22007 "streamline(): Instance is not a 2d or 3d vector field.",
22009 if (_spectrum==2) {
22010 if (is_oriented_only) {
22012 return streamline(func,x,y,z,L,dl,interpolation_type,is_backward_tracking,
true,0,0,0,_width-1.0f,_height-1.0f,0.0f);
22015 return streamline(func,x,y,z,L,dl,interpolation_type,is_backward_tracking,
false,0,0,0,_width-1.0f,_height-1.0f,0.0f);
22018 if (is_oriented_only) {
22020 return streamline(func,x,y,z,L,dl,interpolation_type,is_backward_tracking,
true,0,0,0,_width-1.0f,_height-1.0f,_depth-1.0f);
22023 return streamline(func,x,y,z,L,dl,interpolation_type,is_backward_tracking,
false,0,0,0,_width-1.0f,_height-1.0f,_depth-1.0f);
22044 template<
typename tfunc>
22046 const float x,
const float y,
const float z,
22047 const float L=256,
const float dl=0.1f,
22048 const unsigned int interpolation_type=2,
const bool is_backward_tracking=
false,
22049 const bool is_oriented_only=
false,
22050 const float x0=0,
const float y0=0,
const float z0=0,
22051 const float x1=0,
const float y1=0,
const float z1=0) {
22058 const bool is_bounded = (x0!=x1 || y0!=y1 || z0!=z1);
22059 if (L<=0 || (is_bounded && (x<x0 || x>x1 || y<y0 || y>y1 || z<z0 || z>z1)))
return CImg<floatT>();
22060 const unsigned int size_L = (
unsigned int)
cimg::round(L/dl+1);
22062 const float dl2 = dl/2;
22064 *ptr_x = coordinates.
data(0,0),
22065 *ptr_y = coordinates.
data(0,1),
22066 *ptr_z = coordinates.
data(0,2),
22067 pu = (float)(dl*func(x,y,z,0)),
22068 pv = (
float)(dl*func(x,y,z,1)),
22069 pw = (
float)(dl*func(x,y,z,2)),
22070 X = x, Y = y, Z = z;
22072 switch (interpolation_type) {
22074 cimg_forX(coordinates,l) {
22075 *(ptr_x++) = X; *(ptr_y++) = Y; *(ptr_z++) = Z;
22077 xi = (int)(X>0?X+0.5f:X-0.5f),
22078 yi = (int)(Y>0?Y+0.5f:Y-0.5f),
22079 zi = (int)(Z>0?Z+0.5f:Z-0.5f);
22081 u = (float)(dl*func((
float)xi,(float)yi,(
float)zi,0)),
22082 v = (float)(dl*func((
float)xi,(float)yi,(
float)zi,1)),
22083 w = (float)(dl*func((
float)xi,(float)yi,(
float)zi,2));
22084 if (is_oriented_only && u*pu + v*pv + w*pw<0) { u = -u; v = -v; w = -w; }
22085 if (is_backward_tracking) { X-=(pu=u); Y-=(pv=v); Z-=(pw=w); }
else { X+=(pu=u); Y+=(pv=v); Z+=(pw=w); }
22086 if (is_bounded && (X<x0 || X>x1 || Y<y0 || Y>y1 || Z<z0 || Z>z1))
break;
22090 cimg_forX(coordinates,l) {
22091 *(ptr_x++) = X; *(ptr_y++) = Y; *(ptr_z++) = Z;
22093 u = (float)(dl*func(X,Y,Z,0)),
22094 v = (
float)(dl*func(X,Y,Z,1)),
22095 w = (
float)(dl*func(X,Y,Z,2));
22096 if (is_oriented_only && u*pu + v*pv + w*pw<0) { u = -u; v = -v; w = -w; }
22097 if (is_backward_tracking) { X-=(pu=u); Y-=(pv=v); Z-=(pw=w); }
else { X+=(pu=u); Y+=(pv=v); Z+=(pw=w); }
22098 if (is_bounded && (X<x0 || X>x1 || Y<y0 || Y>y1 || Z<z0 || Z>z1))
break;
22102 cimg_forX(coordinates,l) {
22103 *(ptr_x++) = X; *(ptr_y++) = Y; *(ptr_z++) = Z;
22105 u0 = (float)(dl2*func(X,Y,Z,0)),
22106 v0 = (
float)(dl2*func(X,Y,Z,1)),
22107 w0 = (
float)(dl2*func(X,Y,Z,2));
22108 if (is_oriented_only && u0*pu + v0*pv + w0*pw<0) { u0 = -u0; v0 = -v0; w0 = -w0; }
22110 u = (float)(dl*func(X+u0,Y+v0,Z+w0,0)),
22111 v = (
float)(dl*func(X+u0,Y+v0,Z+w0,1)),
22112 w = (
float)(dl*func(X+u0,Y+v0,Z+w0,2));
22113 if (is_oriented_only && u*pu + v*pv + w*pw<0) { u = -u; v = -v; w = -w; }
22114 if (is_backward_tracking) { X-=(pu=u); Y-=(pv=v); Z-=(pw=w); }
else { X+=(pu=u); Y+=(pv=v); Z+=(pw=w); }
22115 if (is_bounded && (X<x0 || X>x1 || Y<y0 || Y>y1 || Z<z0 || Z>z1))
break;
22119 cimg_forX(coordinates,x) {
22120 *(ptr_x++) = X; *(ptr_y++) = Y; *(ptr_z++) = Z;
22122 u0 = (float)(dl2*func(X,Y,Z,0)),
22123 v0 = (
float)(dl2*func(X,Y,Z,1)),
22124 w0 = (
float)(dl2*func(X,Y,Z,2));
22125 if (is_oriented_only && u0*pu + v0*pv + w0*pw<0) { u0 = -u0; v0 = -v0; w0 = -w0; }
22127 u1 = (float)(dl2*func(X+u0,Y+v0,Z+w0,0)),
22128 v1 = (
float)(dl2*func(X+u0,Y+v0,Z+w0,1)),
22129 w1 = (
float)(dl2*func(X+u0,Y+v0,Z+w0,2));
22130 if (is_oriented_only && u1*pu + v1*pv + w1*pw<0) { u1 = -u1; v1 = -v1; w1 = -w1; }
22132 u2 = (float)(dl2*func(X+u1,Y+v1,Z+w1,0)),
22133 v2 = (
float)(dl2*func(X+u1,Y+v1,Z+w1,1)),
22134 w2 = (
float)(dl2*func(X+u1,Y+v1,Z+w1,2));
22135 if (is_oriented_only && u2*pu + v2*pv + w2*pw<0) { u2 = -u2; v2 = -v2; w2 = -w2; }
22137 u3 = (float)(dl2*func(X+u2,Y+v2,Z+w2,0)),
22138 v3 = (
float)(dl2*func(X+u2,Y+v2,Z+w2,1)),
22139 w3 = (
float)(dl2*func(X+u2,Y+v2,Z+w2,2));
22140 if (is_oriented_only && u2*pu + v2*pv + w2*pw<0) { u3 = -u3; v3 = -v3; w3 = -w3; }
22142 u = (u0 + u3)/3 + (u1 + u2)/1.5f,
22143 v = (v0 + v3)/3 + (v1 + v2)/1.5f,
22144 w = (w0 + w3)/3 + (w1 + w2)/1.5f;
22145 if (is_backward_tracking) { X-=(pu=u); Y-=(pv=v); Z-=(pw=w); }
else { X+=(pu=u); Y+=(pv=v); Z+=(pw=w); }
22146 if (is_bounded && (X<x0 || X>x1 || Y<y0 || Y>y1 || Z<z0 || Z>z1))
break;
22150 if (ptr_x!=coordinates.
data(0,1)) coordinates.
resize((
int)(ptr_x-coordinates.
data()),3,1,1,0);
22151 return coordinates;
22156 const float x,
const float y,
const float z,
22157 const float L=256,
const float dl=0.1f,
22158 const unsigned int interpolation_type=2,
const bool is_backward_tracking=
true,
22159 const bool is_oriented_only=
false,
22160 const float x0=0,
const float y0=0,
const float z0=0,
22161 const float x1=0,
const float y1=0,
const float z1=0) {
22162 _functor4d_streamline_expr func(expression);
22163 return streamline(func,x,y,z,L,dl,interpolation_type,is_backward_tracking,is_oriented_only,x0,y0,z0,x1,y1,z1);
22169 float operator()(
const float x,
const float y,
const float z,
const unsigned int c)
const {
22170 return c<2?(float)ref._linear_atXY(x,y,(
int)z,c):0;
22177 float operator()(
const float x,
const float y,
const float z,
const unsigned int c)
const {
22178 return (
float)ref._linear_atXYZ(x,y,z,c);
22187 float operator()(
const float x,
const float y,
const float z,
const unsigned int c)
const {
22188 #define _cimg_vecalign2d(i,j) if (I(i,j,0)*I(0,0,0)+I(i,j,1)*I(0,0,1)<0) { I(i,j,0) = -I(i,j,0); I(i,j,1) = -I(i,j,1); }
22190 xi = (int)x - (x>=0?0:1), nxi = xi + 1,
22191 yi = (int)y - (y>=0?0:1), nyi = yi + 1,
22198 if (xi<0) xi = 0;
if (nxi<0) nxi = 0;
22199 if (xi>=ref.width()) xi = ref.width()-1;
if (nxi>=ref.width()) nxi = ref.width()-1;
22200 if (yi<0) yi = 0;
if (nyi<0) nyi = 0;
22201 if (yi>=ref.height()) yi = ref.height()-1;
if (nyi>=ref.height()) nyi = ref.height()-1;
22202 I(0,0,0) = (float)ref(xi,yi,zi,0); I(0,0,1) = (float)ref(xi,yi,zi,1);
22203 I(1,0,0) = (float)ref(nxi,yi,zi,0); I(1,0,1) = (float)ref(nxi,yi,zi,1);
22204 I(1,1,0) = (float)ref(nxi,nyi,zi,0); I(1,1,1) = (float)ref(nxi,nyi,zi,1);
22205 I(0,1,0) = (float)ref(xi,nyi,zi,0); I(0,1,1) = (float)ref(xi,nyi,zi,1);
22206 _cimg_vecalign2d(1,0); _cimg_vecalign2d(1,1); _cimg_vecalign2d(0,1);
22208 return c<2?(float)pI->_linear_atXY(dx,dy,0,c):0;
22217 float operator()(
const float x,
const float y,
const float z,
const unsigned int c)
const {
22218 #define _cimg_vecalign3d(i,j,k) if (I(i,j,k,0)*I(0,0,0,0)+I(i,j,k,1)*I(0,0,0,1)+I(i,j,k,2)*I(0,0,0,2)<0) { \
22219 I(i,j,k,0) = -I(i,j,k,0); I(i,j,k,1) = -I(i,j,k,1); I(i,j,k,2) = -I(i,j,k,2); }
22221 xi = (int)x - (x>=0?0:1), nxi = xi + 1,
22222 yi = (int)y - (y>=0?0:1), nyi = yi + 1,
22223 zi = (int)z - (z>=0?0:1), nzi = zi + 1;
22230 if (xi<0) xi = 0;
if (nxi<0) nxi = 0;
22231 if (xi>=ref.width()) xi = ref.width()-1;
if (nxi>=ref.width()) nxi = ref.width()-1;
22232 if (yi<0) yi = 0;
if (nyi<0) nyi = 0;
22233 if (yi>=ref.height()) yi = ref.height()-1;
if (nyi>=ref.height()) nyi = ref.height()-1;
22234 if (zi<0) zi = 0;
if (nzi<0) nzi = 0;
22235 if (zi>=ref.depth()) zi = ref.depth()-1;
if (nzi>=ref.depth()) nzi = ref.depth()-1;
22236 I(0,0,0,0) = (float)ref(xi,yi,zi,0); I(0,0,0,1) = (float)ref(xi,yi,zi,1); I(0,0,0,2) = (float)ref(xi,yi,zi,2);
22237 I(1,0,0,0) = (float)ref(nxi,yi,zi,0); I(1,0,0,1) = (float)ref(nxi,yi,zi,1); I(1,0,0,2) = (float)ref(nxi,yi,zi,2);
22238 I(1,1,0,0) = (float)ref(nxi,nyi,zi,0); I(1,1,0,1) = (float)ref(nxi,nyi,zi,1); I(1,1,0,2) = (float)ref(nxi,nyi,zi,2);
22239 I(0,1,0,0) = (float)ref(xi,nyi,zi,0); I(0,1,0,1) = (float)ref(xi,nyi,zi,1); I(0,1,0,2) = (float)ref(xi,yi,zi,2);
22240 I(0,0,0,1) = (float)ref(xi,yi,nzi,0); I(0,0,0,1) = (float)ref(xi,yi,nzi,1); I(0,0,0,2) = (float)ref(xi,yi,nzi,2);
22241 I(1,0,0,1) = (float)ref(nxi,yi,nzi,0); I(1,0,0,1) = (float)ref(nxi,yi,nzi,1); I(1,0,0,2) = (float)ref(nxi,yi,nzi,2);
22242 I(1,1,0,1) = (float)ref(nxi,nyi,nzi,0); I(1,1,0,1) = (float)ref(nxi,nyi,nzi,1); I(1,1,0,2) = (float)ref(nxi,nyi,nzi,2);
22243 I(0,1,0,1) = (float)ref(xi,nyi,nzi,0); I(0,1,0,1) = (float)ref(xi,nyi,nzi,1); I(0,1,0,2) = (float)ref(xi,yi,nzi,2);
22244 _cimg_vecalign3d(1,0,0); _cimg_vecalign3d(1,1,0); _cimg_vecalign3d(0,1,0);
22245 _cimg_vecalign3d(0,0,1); _cimg_vecalign3d(1,0,1); _cimg_vecalign3d(1,1,1); _cimg_vecalign3d(0,1,1);
22247 return (
float)pI->_linear_atXYZ(dx,dy,dz,c);
22255 float operator()(
const float x,
const float y,
const float z,
const unsigned int c)
const {
22256 return (
float)mp->eval(x,y,z,c);
22269 const unsigned int y0=0,
const unsigned int z0=0,
const unsigned int c0=0) {
22270 const unsigned int beg = (
unsigned int)
offset(x0,y0,z0,c0),
end =
offset(x1,y0,z0,c0);
22273 "get_shared_points(): Invalid request of a shared-memory subset (%u->%u,%u,%u,%u).",
22277 return CImg<T>(_data+beg,x1-x0+1,1,1,1,
true);
22282 const unsigned int y0=0,
const unsigned int z0=0,
const unsigned int c0=0)
const {
22283 const unsigned int beg = (
unsigned int)
offset(x0,y0,z0,c0),
end =
offset(x1,y0,z0,c0);
22286 "get_shared_points(): Invalid request of a shared-memory subset (%u->%u,%u,%u,%u).",
22290 return CImg<T>(_data+beg,x1-x0+1,1,1,1,
true);
22301 const unsigned int z0=0,
const unsigned int c0=0) {
22302 const unsigned int beg =
offset(0,y0,z0,c0),
end =
offset(0,y1,z0,c0);
22305 "get_shared_rows(): Invalid request of a shared-memory subset (0->%u,%u->%u,%u,%u).",
22307 _width-1,y0,y1,z0,c0);
22309 return CImg<T>(_data+beg,_width,y1-y0+1,1,1,
true);
22314 const unsigned int z0=0,
const unsigned int c0=0)
const {
22315 const unsigned int beg =
offset(0,y0,z0,c0),
end =
offset(0,y1,z0,c0);
22318 "get_shared_rows(): Invalid request of a shared-memory subset (0->%u,%u->%u,%u,%u).",
22320 _width-1,y0,y1,z0,c0);
22322 return CImg<T>(_data+beg,_width,y1-y0+1,1,1,
true);
22350 "get_shared_slices(): Invalid request of a shared-memory subset (0->%u,0->%u,%u->%u,%u).",
22352 _width-1,_height-1,z0,z1,c0);
22354 return CImg<T>(_data+beg,_width,_height,z1-z0+1,1,
true);
22362 "get_shared_slices(): Invalid request of a shared-memory subset (0->%u,0->%u,%u->%u,%u).",
22364 _width-1,_height-1,z0,z1,c0);
22366 return CImg<T>(_data+beg,_width,_height,z1-z0+1,1,
true);
22392 "get_shared_channels(): Invalid request of a shared-memory subset (0->%u,0->%u,0->%u,%u->%u).",
22394 _width-1,_height-1,_depth-1,c0,c1);
22396 return CImg<T>(_data+beg,_width,_height,_depth,c1-c0+1,
true);
22404 "get_shared_channels(): Invalid request of a shared-memory subset (0->%u,0->%u,0->%u,%u->%u).",
22406 _width-1,_height-1,_depth-1,c0,c1);
22408 return CImg<T>(_data+beg,_width,_height,_depth,c1-c0+1,
true);
22426 return CImg<T>(_data,_width,_height,_depth,_spectrum,
true);
22431 return CImg<T>(_data,_width,_height,_depth,_spectrum,
true);
22448 const unsigned int dp = (
unsigned int)(nb?-nb:1);
22452 for (
int pe=_width-dp; p<pe; p+=dp)
get_crop(p,0,0,0,p+dp-1,_height-1,_depth-1,_spectrum-1).move_to(res);
22453 get_crop(p,0,0,0,_width-1,_height-1,_depth-1,_spectrum-1).move_to(res);
22456 for (
int pe=_height-dp; p<pe; p+=dp)
get_crop(0,p,0,0,_width-1,p+dp-1,_depth-1,_spectrum-1).move_to(res);
22457 get_crop(0,p,0,0,_width-1,_height-1,_depth-1,_spectrum-1).move_to(res);
22460 for (
int pe=_depth-dp; p<pe; p+=dp)
get_crop(0,0,p,0,_width-1,_height-1,p+dp-1,_spectrum-1).move_to(res);
22461 get_crop(0,0,p,0,_width-1,_height-1,_depth-1,_spectrum-1).move_to(res);
22464 for (
int pe=_spectrum-dp; p<pe; p+=dp)
get_crop(0,0,0,p,_width-1,_height-1,_depth-1,p+dp-1).move_to(res);
22465 get_crop(0,0,0,p,_width-1,_height-1,_depth-1,_spectrum-1).move_to(res);
22470 const unsigned int siz = _axis==
'x'?_width:_axis==
'y'?_height:_axis==
'z'?_depth:_axis==
'c'?_spectrum:0;
22471 if ((
unsigned int)nb>siz)
22473 "get_split(): Instance cannot be split along %c-axis into %u blocs.",
22476 int err = (int)siz;
22477 unsigned int _p = 0;
22480 cimg_forX(*
this,p)
if ((err-=nb)<=0) {
22481 get_crop(_p,0,0,0,p,_height-1,_depth-1,_spectrum-1).move_to(res);
22487 cimg_forY(*
this,p)
if ((err-=nb)<=0) {
22488 get_crop(0,_p,0,0,_width-1,p,_depth-1,_spectrum-1).move_to(res);
22494 cimg_forZ(*
this,p)
if ((err-=nb)<=0) {
22495 get_crop(0,0,_p,0,_width-1,_height-1,p,_spectrum-1).move_to(res);
22501 cimg_forC(*
this,p)
if ((err-=nb)<=0) {
22502 get_crop(0,0,0,_p,_width-1,_height-1,_depth-1,p).move_to(res);
22520 for (
const T *ps = _data, *_ps = ps, *
const pe =
end(); ps<pe; ) {
22521 while (_ps<pe && *_ps==value) ++_ps;
22522 unsigned int siz = _ps - ps;
22523 if (siz && keep_values) res.
insert(
CImg<T>(ps,1,siz,1,1,is_shared),~0U,is_shared);
22525 while (_ps<pe && *_ps!=value) ++_ps;
22527 if (siz) res.
insert(
CImg<T>(ps,1,siz,1,1,is_shared),~0U,is_shared);
22539 template<
typename t>
22542 if (values.size()==1)
return get_split(*values,keep_values,is_shared);
22544 const t *pve = values.end();
22545 for (
const T *ps = _data, *_ps = ps, *
const pe =
end(); ps<pe; ) {
22551 const T *__ps = _ps;
22552 while (__ps<pe && pv<pve && *__ps==(T)*pv) { ++__ps; ++pv; }
22553 if (pv==pve) _ps = __ps;
22555 unsigned int siz = _ps - ps;
22556 if (siz && keep_values) res.
insert(
CImg<T>(ps,1,siz,1,1,is_shared),~0U,is_shared);
22562 while (_ps<pe && *_ps!=(T)*pv) ++_ps;
22564 const T *__ps = _ps + 1;
22566 while (__ps<pe && pv<pve && *__ps==(T)*pv) { ++__ps; ++pv; }
22567 if (pv!=pve) _ps = __ps;
22569 }
while (_ps<pe && pv!=pve);
22573 if (siz) res.
insert(
CImg<T>(ps,1,siz,1,1,is_shared),~0U,is_shared);
22585 template<
typename t>
22588 if (!img)
return *
this;
22595 if (!img)
return *
this;
22600 template<
typename t>
22603 if (!img)
return +*
this;
22610 if (!img)
return +*
this;
22629 template<
typename t>
22631 if (
is_empty() || !mask)
return *
this;
22632 return get_correlate(mask,boundary_conditions,is_normalized).move_to(*
this);
22636 template<
typename t>
22638 const bool is_normalized=
false)
const {
22639 if (
is_empty() || !mask)
return *
this;
22640 typedef _cimg_Ttfloat Ttfloat;
22642 if (boundary_conditions && mask._width==mask._height && ((mask._depth==1 && mask._width<=5) || (mask._depth==mask._width && mask._width<=3))) {
22644 Ttfloat *ptrd = res._data;
22645 switch (mask._depth) {
22650 const CImg<t> _mask = mask.get_shared_channel(c%mask._spectrum);
22651 if (is_normalized) {
22652 const Ttfloat _M = (Ttfloat)_mask.magnitude(2), M = _M*_M;
22653 cimg_for3x3x3(_img,x,y,z,0,I,T) {
22654 const Ttfloat N = M*(I[ 0]*I[ 0] + I[ 1]*I[ 1] + I[ 2]*I[ 2] +
22655 I[ 3]*I[ 3] + I[ 4]*I[ 4] + I[ 5]*I[ 5] +
22656 I[ 6]*I[ 6] + I[ 7]*I[ 7] + I[ 8]*I[ 8] +
22657 I[ 9]*I[ 9] + I[10]*I[10] + I[11]*I[11] +
22658 I[12]*I[12] + I[13]*I[13] + I[14]*I[14] +
22659 I[15]*I[15] + I[16]*I[16] + I[17]*I[17] +
22660 I[18]*I[18] + I[19]*I[19] + I[20]*I[20] +
22661 I[21]*I[21] + I[22]*I[22] + I[23]*I[23] +
22662 I[24]*I[24] + I[25]*I[25] + I[26]*I[26]);
22663 *(ptrd++) = (Ttfloat)(N?(I[ 0]*_mask[ 0] + I[ 1]*_mask[ 1] + I[ 2]*_mask[ 2] +
22664 I[ 3]*_mask[ 3] + I[ 4]*_mask[ 4] + I[ 5]*_mask[ 5] +
22665 I[ 6]*_mask[ 6] + I[ 7]*_mask[ 7] + I[ 8]*_mask[ 8] +
22666 I[ 9]*_mask[ 9] + I[10]*_mask[10] + I[11]*_mask[11] +
22667 I[12]*_mask[12] + I[13]*_mask[13] + I[14]*_mask[14] +
22668 I[15]*_mask[15] + I[16]*_mask[16] + I[17]*_mask[17] +
22669 I[18]*_mask[18] + I[19]*_mask[19] + I[20]*_mask[20] +
22670 I[21]*_mask[21] + I[22]*_mask[22] + I[23]*_mask[23] +
22671 I[24]*_mask[24] + I[25]*_mask[25] + I[26]*_mask[26])/std::sqrt(N):0);
22673 }
else cimg_for3x3x3(_img,x,y,z,0,I,T)
22674 *(ptrd++) = (Ttfloat)(I[ 0]*_mask[ 0] + I[ 1]*_mask[ 1] + I[ 2]*_mask[ 2] +
22675 I[ 3]*_mask[ 3] + I[ 4]*_mask[ 4] + I[ 5]*_mask[ 5] +
22676 I[ 6]*_mask[ 6] + I[ 7]*_mask[ 7] + I[ 8]*_mask[ 8] +
22677 I[ 9]*_mask[ 9] + I[10]*_mask[10] + I[11]*_mask[11] +
22678 I[12]*_mask[12] + I[13]*_mask[13] + I[14]*_mask[14] +
22679 I[15]*_mask[15] + I[16]*_mask[16] + I[17]*_mask[17] +
22680 I[18]*_mask[18] + I[19]*_mask[19] + I[20]*_mask[20] +
22681 I[21]*_mask[21] + I[22]*_mask[22] + I[23]*_mask[23] +
22682 I[24]*_mask[24] + I[25]*_mask[25] + I[26]*_mask[26]);
22689 const CImg<t> _mask = mask.get_shared_channel(c%mask._spectrum);
22690 if (is_normalized) {
22691 const Ttfloat _M = (Ttfloat)_mask.magnitude(2), M = _M*_M;
22692 cimg_for2x2x2(_img,x,y,z,0,I,T) {
22693 const Ttfloat N = M*(I[0]*I[0] + I[1]*I[1] +
22694 I[2]*I[2] + I[3]*I[3] +
22695 I[4]*I[4] + I[5]*I[5] +
22696 I[6]*I[6] + I[7]*I[7]);
22697 *(ptrd++) = (Ttfloat)(N?(I[0]*_mask[0] + I[1]*_mask[1] +
22698 I[2]*_mask[2] + I[3]*_mask[3] +
22699 I[4]*_mask[4] + I[5]*_mask[5] +
22700 I[6]*_mask[6] + I[7]*_mask[7])/std::sqrt(N):0);
22702 }
else cimg_for2x2x2(_img,x,y,z,0,I,T)
22703 *(ptrd++) = (Ttfloat)(I[0]*_mask[0] + I[1]*_mask[1] +
22704 I[2]*_mask[2] + I[3]*_mask[3] +
22705 I[4]*_mask[4] + I[5]*_mask[5] +
22706 I[6]*_mask[6] + I[7]*_mask[7]);
22711 switch (mask._width) {
22716 const CImg<t> _mask = mask.get_shared_channel(c%mask._spectrum);
22717 if (is_normalized) {
22718 const Ttfloat _M = (Ttfloat)_mask.magnitude(2), M = _M*_M;
22719 cimg_forZ(_img,z) cimg_for6x6(_img,x,y,z,0,I,T) {
22720 const Ttfloat N = M*(I[ 0]*I[ 0] + I[ 1]*I[ 1] + I[ 2]*I[ 2] + I[ 3]*I[ 3] + I[ 4]*I[ 4] + I[ 5]*I[ 5] +
22721 I[ 6]*I[ 6] + I[ 7]*I[ 7] + I[ 8]*I[ 8] + I[ 9]*I[ 9] + I[10]*I[10] + I[11]*I[11] +
22722 I[12]*I[12] + I[13]*I[13] + I[14]*I[14] + I[15]*I[15] + I[16]*I[16] + I[17]*I[17] +
22723 I[18]*I[18] + I[19]*I[19] + I[20]*I[20] + I[21]*I[21] + I[22]*I[22] + I[23]*I[23] +
22724 I[24]*I[24] + I[25]*I[25] + I[26]*I[26] + I[27]*I[27] + I[28]*I[28] + I[29]*I[29] +
22725 I[30]*I[30] + I[31]*I[31] + I[32]*I[32] + I[33]*I[33] + I[34]*I[34] + I[35]*I[35]);
22726 *(ptrd++) = (Ttfloat)(N?(I[ 0]*_mask[ 0] + I[ 1]*_mask[ 1] + I[ 2]*_mask[ 2] + I[ 3]*_mask[ 3] + I[ 4]*_mask[ 4] + I[ 5]*_mask[ 5] +
22727 I[ 6]*_mask[ 6] + I[ 7]*_mask[ 7] + I[ 8]*_mask[ 8] + I[ 9]*_mask[ 9] + I[10]*_mask[10] + I[11]*_mask[11] +
22728 I[12]*_mask[12] + I[13]*_mask[13] + I[14]*_mask[14] + I[15]*_mask[15] + I[16]*_mask[16] + I[17]*_mask[17] +
22729 I[18]*_mask[18] + I[19]*_mask[19] + I[20]*_mask[20] + I[21]*_mask[21] + I[22]*_mask[22] + I[23]*_mask[23] +
22730 I[24]*_mask[24] + I[25]*_mask[25] + I[26]*_mask[26] + I[27]*_mask[27] + I[28]*_mask[28] + I[29]*_mask[29] +
22731 I[30]*_mask[30] + I[31]*_mask[31] + I[32]*_mask[32] + I[33]*_mask[33] + I[34]*_mask[34] + I[35]*_mask[35])/std::sqrt(N):0);
22733 }
else cimg_forZ(_img,z) cimg_for6x6(_img,x,y,z,0,I,T)
22734 *(ptrd++) = (Ttfloat)(I[ 0]*_mask[ 0] + I[ 1]*_mask[ 1] + I[ 2]*_mask[ 2] + I[ 3]*_mask[ 3] + I[ 4]*_mask[ 4] + I[ 5]*_mask[ 5] +
22735 I[ 6]*_mask[ 6] + I[ 7]*_mask[ 7] + I[ 8]*_mask[ 8] + I[ 9]*_mask[ 9] + I[10]*_mask[10] + I[11]*_mask[11] +
22736 I[12]*_mask[12] + I[13]*_mask[13] + I[14]*_mask[14] + I[15]*_mask[15] + I[16]*_mask[16] + I[17]*_mask[17] +
22737 I[18]*_mask[18] + I[19]*_mask[19] + I[20]*_mask[20] + I[21]*_mask[21] + I[22]*_mask[22] + I[23]*_mask[23] +
22738 I[24]*_mask[24] + I[25]*_mask[25] + I[26]*_mask[26] + I[27]*_mask[27] + I[28]*_mask[28] + I[29]*_mask[29] +
22739 I[30]*_mask[30] + I[31]*_mask[31] + I[32]*_mask[32] + I[33]*_mask[33] + I[34]*_mask[34] + I[35]*_mask[35]);
22746 const CImg<t> _mask = mask.get_shared_channel(c%mask._spectrum);
22747 if (is_normalized) {
22748 const Ttfloat _M = (Ttfloat)_mask.magnitude(2), M = _M*_M;
22749 cimg_forZ(_img,z) cimg_for5x5(_img,x,y,z,0,I,T) {
22750 const Ttfloat N = M*(I[ 0]*I[ 0] + I[ 1]*I[ 1] + I[ 2]*I[ 2] + I[ 3]*I[ 3] + I[ 4]*I[ 4] +
22751 I[ 5]*I[ 5] + I[ 6]*I[ 6] + I[ 7]*I[ 7] + I[ 8]*I[ 8] + I[ 9]*I[ 9] +
22752 I[10]*I[10] + I[11]*I[11] + I[12]*I[12] + I[13]*I[13] + I[14]*I[14] +
22753 I[15]*I[15] + I[16]*I[16] + I[17]*I[17] + I[18]*I[18] + I[19]*I[19] +
22754 I[20]*I[20] + I[21]*I[21] + I[22]*I[22] + I[23]*I[23] + I[24]*I[24]);
22755 *(ptrd++) = (Ttfloat)(N?(I[ 0]*_mask[ 0] + I[ 1]*_mask[ 1] + I[ 2]*_mask[ 2] + I[ 3]*_mask[ 3] + I[ 4]*_mask[ 4] +
22756 I[ 5]*_mask[ 5] + I[ 6]*_mask[ 6] + I[ 7]*_mask[ 7] + I[ 8]*_mask[ 8] + I[ 9]*_mask[ 9] +
22757 I[10]*_mask[10] + I[11]*_mask[11] + I[12]*_mask[12] + I[13]*_mask[13] + I[14]*_mask[14] +
22758 I[15]*_mask[15] + I[16]*_mask[16] + I[17]*_mask[17] + I[18]*_mask[18] + I[19]*_mask[19] +
22759 I[20]*_mask[20] + I[21]*_mask[21] + I[22]*_mask[22] + I[23]*_mask[23] + I[24]*_mask[24])/std::sqrt(N):0);
22761 }
else cimg_forZ(_img,z) cimg_for5x5(_img,x,y,z,0,I,T)
22762 *(ptrd++) = (Ttfloat)(I[ 0]*_mask[ 0] + I[ 1]*_mask[ 1] + I[ 2]*_mask[ 2] + I[ 3]*_mask[ 3] + I[ 4]*_mask[ 4] +
22763 I[ 5]*_mask[ 5] + I[ 6]*_mask[ 6] + I[ 7]*_mask[ 7] + I[ 8]*_mask[ 8] + I[ 9]*_mask[ 9] +
22764 I[10]*_mask[10] + I[11]*_mask[11] + I[12]*_mask[12] + I[13]*_mask[13] + I[14]*_mask[14] +
22765 I[15]*_mask[15] + I[16]*_mask[16] + I[17]*_mask[17] + I[18]*_mask[18] + I[19]*_mask[19] +
22766 I[20]*_mask[20] + I[21]*_mask[21] + I[22]*_mask[22] + I[23]*_mask[23] + I[24]*_mask[24]);
22773 const CImg<t> _mask = mask.get_shared_channel(c%mask._spectrum);
22774 if (is_normalized) {
22775 const Ttfloat _M = (Ttfloat)_mask.magnitude(2), M = _M*_M;
22776 cimg_forZ(_img,z) cimg_for4x4(_img,x,y,z,0,I,T) {
22777 const Ttfloat N = M*(I[ 0]*I[ 0] + I[ 1]*I[ 1] + I[ 2]*I[ 2] + I[ 3]*I[ 3] +
22778 I[ 4]*I[ 4] + I[ 5]*I[ 5] + I[ 6]*I[ 6] + I[ 7]*I[ 7] +
22779 I[ 8]*I[ 8] + I[ 9]*I[ 9] + I[10]*I[10] + I[11]*I[11] +
22780 I[12]*I[12] + I[13]*I[13] + I[14]*I[14] + I[15]*I[15]);
22781 *(ptrd++) = (Ttfloat)(N?(I[ 0]*_mask[ 0] + I[ 1]*_mask[ 1] + I[ 2]*_mask[ 2] + I[ 3]*_mask[ 3] +
22782 I[ 4]*_mask[ 4] + I[ 5]*_mask[ 5] + I[ 6]*_mask[ 6] + I[ 7]*_mask[ 7] +
22783 I[ 8]*_mask[ 8] + I[ 9]*_mask[ 9] + I[10]*_mask[10] + I[11]*_mask[11] +
22784 I[12]*_mask[12] + I[13]*_mask[13] + I[14]*_mask[14] + I[15]*_mask[15])/std::sqrt(N):0);
22786 }
else cimg_forZ(_img,z) cimg_for4x4(_img,x,y,z,0,I,T)
22787 *(ptrd++) = (Ttfloat)(I[ 0]*_mask[ 0] + I[ 1]*_mask[ 1] + I[ 2]*_mask[ 2] + I[ 3]*_mask[ 3] +
22788 I[ 4]*_mask[ 4] + I[ 5]*_mask[ 5] + I[ 6]*_mask[ 6] + I[ 7]*_mask[ 7] +
22789 I[ 8]*_mask[ 8] + I[ 9]*_mask[ 9] + I[10]*_mask[10] + I[11]*_mask[11] +
22790 I[12]*_mask[12] + I[13]*_mask[13] + I[14]*_mask[14] + I[15]*_mask[15]);
22797 const CImg<t> _mask = mask.get_shared_channel(c%mask._spectrum);
22798 if (is_normalized) {
22799 const Ttfloat _M = (Ttfloat)_mask.magnitude(2), M = _M*_M;
22800 cimg_forZ(_img,z) cimg_for3x3(_img,x,y,z,0,I,T) {
22801 const Ttfloat N = M*(I[0]*I[0] + I[1]*I[1] + I[2]*I[2] +
22802 I[3]*I[3] + I[4]*I[4] + I[5]*I[5] +
22803 I[6]*I[6] + I[7]*I[7] + I[8]*I[8]);
22804 *(ptrd++) = (Ttfloat)(N?(I[0]*_mask[0] + I[1]*_mask[1] + I[2]*_mask[2] +
22805 I[3]*_mask[3] + I[4]*_mask[4] + I[5]*_mask[5] +
22806 I[6]*_mask[6] + I[7]*_mask[7] + I[8]*_mask[8])/std::sqrt(N):0);
22808 }
else cimg_forZ(_img,z) cimg_for3x3(_img,x,y,z,0,I,T)
22809 *(ptrd++) = (Ttfloat)(I[0]*_mask[0] + I[1]*_mask[1] + I[2]*_mask[2] +
22810 I[3]*_mask[3] + I[4]*_mask[4] + I[5]*_mask[5] +
22811 I[6]*_mask[6] + I[7]*_mask[7] + I[8]*_mask[8]);
22818 const CImg<t> _mask = mask.get_shared_channel(c%mask._spectrum);
22819 if (is_normalized) {
22820 const Ttfloat _M = (Ttfloat)_mask.magnitude(2), M = _M*_M;
22821 cimg_forZ(_img,z) cimg_for2x2(_img,x,y,z,0,I,T) {
22822 const Ttfloat N = M*(I[0]*I[0] + I[1]*I[1] +
22823 I[2]*I[2] + I[3]*I[3]);
22824 *(ptrd++) = (Ttfloat)(N?(I[0]*_mask[0] + I[1]*_mask[1] +
22825 I[2]*_mask[2] + I[3]*_mask[3])/std::sqrt(N):0);
22827 }
else cimg_forZ(_img,z) cimg_for2x2(_img,x,y,z,0,I,T)
22828 *(ptrd++) = (Ttfloat)(I[0]*_mask[0] + I[1]*_mask[1] +
22829 I[2]*_mask[2] + I[3]*_mask[3]);
22833 if (is_normalized) res.fill(1);
22834 else cimg_forC(res,c) {
22836 const CImg<t> _mask = mask.get_shared_channel(c%mask._spectrum);
22837 res.get_shared_channel(c).assign(_img)*=_mask[0];
22844 mx2 = mask.width()/2, my2 = mask.height()/2, mz2 = mask.depth()/2,
22845 mx1 = mx2 - 1 + (mask.width()%2), my1 = my2 - 1 + (mask.height()%2), mz1 = mz2 - 1 + (mask.depth()%2),
22849 const CImg<t> _mask = mask.get_shared_channel(c%mask._spectrum);
22850 if (is_normalized) {
22851 const Ttfloat _M = (Ttfloat)_mask.magnitude(2), M = _M*_M;
22852 for (
int z = mz1; z<mze; ++z)
22853 for (
int y = my1; y<mye; ++y)
22854 for (
int x = mx1; x<mxe; ++x) {
22855 Ttfloat val = 0, N = 0;
22856 for (
int zm = -mz1; zm<=mz2; ++zm)
22857 for (
int ym = -my1; ym<=my2; ++ym)
22858 for (
int xm = -mx1; xm<=mx2; ++xm) {
22859 const Ttfloat _val = (Ttfloat)_img(x+xm,y+ym,z+zm);
22860 val+=_val*_mask(mx1+xm,my1+ym,mz1+zm);
22864 res(x,y,z,c) = (Ttfloat)(N?val/std::sqrt(N):0);
22866 if (boundary_conditions)
22867 cimg_forYZ(res,y,z)
22868 for (
int x = 0; x<width(); (y<my1 || y>=mye || z<mz1 || z>=mze)?++x:((x<mx1-1 || x>=mxe)?++x:(x=mxe))) {
22869 Ttfloat val = 0, N = 0;
22870 for (
int zm = -mz1; zm<=mz2; ++zm)
22871 for (
int ym = -my1; ym<=my2; ++ym)
22872 for (
int xm = -mx1; xm<=mx2; ++xm) {
22873 const Ttfloat _val = (Ttfloat)_img._atXYZ(x+xm,y+ym,z+zm);
22874 val+=_val*_mask(mx1+xm,my1+ym,mz1+zm);
22878 res(x,y,z,c) = (Ttfloat)(N?val/std::sqrt(N):0);
22881 cimg_forYZ(res,y,z)
22882 for (
int x = 0; x<width(); (y<my1 || y>=mye || z<mz1 || z>=mze)?++x:((x<mx1-1 || x>=mxe)?++x:(x=mxe))) {
22883 Ttfloat val = 0, N = 0;
22884 for (
int zm = -mz1; zm<=mz2; ++zm)
22885 for (
int ym = -my1; ym<=my2; ++ym)
22886 for (
int xm = -mx1; xm<=mx2; ++xm) {
22887 const Ttfloat _val = (Ttfloat)_img.atXYZ(x+xm,y+ym,z+zm,0,0);
22888 val+=_val*_mask(mx1+xm,my1+ym,mz1+zm);
22892 res(x,y,z,c) = (Ttfloat)(N?val/std::sqrt(N):0);
22895 for (
int z = mz1; z<mze; ++z)
22896 for (
int y = my1; y<mye; ++y)
22897 for (
int x = mx1; x<mxe; ++x) {
22899 for (
int zm = -mz1; zm<=mz2; ++zm)
22900 for (
int ym = -my1; ym<=my2; ++ym)
22901 for (
int xm = -mx1; xm<=mx2; ++xm)
22902 val+=_img(x+xm,y+ym,z+zm)*_mask(mx1+xm,my1+ym,mz1+zm);
22903 res(x,y,z,c) = (Ttfloat)val;
22905 if (boundary_conditions)
22906 cimg_forYZ(res,y,z)
22907 for (
int x = 0; x<width(); (y<my1 || y>=mye || z<mz1 || z>=mze)?++x:((x<mx1-1 || x>=mxe)?++x:(x=mxe))) {
22909 for (
int zm = -mz1; zm<=mz2; ++zm)
22910 for (
int ym = -my1; ym<=my2; ++ym)
22911 for (
int xm = -mx1; xm<=mx2; ++xm)
22912 val+=_img._atXYZ(x+xm,y+ym,z+zm)*_mask(mx1+xm,my1+ym,mz1+zm);
22913 res(x,y,z,c) = (Ttfloat)val;
22916 cimg_forYZ(res,y,z)
22917 for (
int x = 0; x<width(); (y<my1 || y>=mye || z<mz1 || z>=mze)?++x:((x<mx1-1 || x>=mxe)?++x:(x=mxe))) {
22919 for (
int zm = -mz1; zm<=mz2; ++zm)
22920 for (
int ym = -my1; ym<=my2; ++ym)
22921 for (
int xm = -mx1; xm<=mx2; ++xm)
22922 val+=_img.atXYZ(x+xm,y+ym,z+zm,0,0)*_mask(mx1+xm,my1+ym,mz1+zm);
22923 res(x,y,z,c) = (Ttfloat)val;
22939 template<
typename t>
22941 if (
is_empty() || !mask)
return *
this;
22942 return get_convolve(mask,boundary_conditions,is_normalized).move_to(*
this);
22946 template<
typename t>
22948 const bool is_normalized=
false)
const {
22949 if (
is_empty() || !mask)
return *
this;
22959 template<
typename t>
22961 if (
is_empty() || !mask)
return *
this;
22962 return get_erode(mask,boundary_conditions,is_normalized).move_to(*
this);
22966 template<
typename t>
22968 const bool is_normalized=
false)
const {
22969 if (
is_empty() || !mask)
return *
this;
22970 typedef _cimg_Tt Tt;
22973 mx2 = mask.width()/2, my2 = mask.height()/2, mz2 = mask.depth()/2,
22974 mx1 = mx2 - 1 + (mask.width()%2), my1 = my2 - 1 + (mask.height()%2), mz1 = mz2 - 1 + (mask.depth()%2),
22976 cimg_forC(*
this,c) {
22978 const CImg<t> _mask = mask.get_shared_channel(c%mask._spectrum);
22979 if (is_normalized) {
22980 for (
int z = mz1; z<mze; ++z)
22981 for (
int y = my1; y<mye; ++y)
22982 for (
int x = mx1; x<mxe; ++x) {
22984 for (
int zm = -mz1; zm<=mz2; ++zm)
22985 for (
int ym = -my1; ym<=my2; ++ym)
22986 for (
int xm = -mx1; xm<=mx2; ++xm) {
22987 const t mval = _mask(mx1+xm,my1+ym,mz1+zm);
22988 const Tt cval = (Tt)(_img(x+xm,y+ym,z+zm) + mval);
22989 if (mval && cval<min_val) min_val = cval;
22991 res(x,y,z,c) = min_val;
22993 if (boundary_conditions)
22994 cimg_forYZ(res,y,z)
22995 for (
int x = 0; x<width(); (y<my1 || y>=mye || z<mz1 || z>=mze)?++x:((x<mx1-1 || x>=mxe)?++x:(x=mxe))) {
22997 for (
int zm = -mz1; zm<=mz2; ++zm)
22998 for (
int ym = -my1; ym<=my2; ++ym)
22999 for (
int xm = -mx1; xm<=mx2; ++xm) {
23000 const t mval = _mask(mx1+xm,my1+ym,mz1+zm);
23001 const Tt cval = (Tt)(_img._atXYZ(x+xm,y+ym,z+zm) + mval);
23002 if (mval && cval<min_val) min_val = cval;
23004 res(x,y,z,c) = min_val;
23007 cimg_forYZ(res,y,z)
23008 for (
int x = 0; x<width(); (y<my1 || y>=mye || z<mz1 || z>=mze)?++x:((x<mx1-1 || x>=mxe)?++x:(x=mxe))) {
23010 for (
int zm = -mz1; zm<=mz2; ++zm)
23011 for (
int ym = -my1; ym<=my2; ++ym)
23012 for (
int xm = -mx1; xm<=mx2; ++xm) {
23013 const t mval = _mask(mx1+xm,my1+ym,mz1+zm);
23014 const Tt cval = (Tt)(_img.atXYZ(x+xm,y+ym,z+zm,0,0) + mval);
23015 if (mval && cval<min_val) min_val = cval;
23017 res(x,y,z,c) = min_val;
23020 for (
int z = mz1; z<mze; ++z)
23021 for (
int y = my1; y<mye; ++y)
23022 for (
int x = mx1; x<mxe; ++x) {
23024 for (
int zm = -mz1; zm<=mz2; ++zm)
23025 for (
int ym = -my1; ym<=my2; ++ym)
23026 for (
int xm = -mx1; xm<=mx2; ++xm) {
23027 const Tt cval = (Tt)_img(x+xm,y+ym,z+zm);
23028 if (_mask(mx1+xm,my1+ym,mz1+zm) && cval<min_val) min_val = cval;
23030 res(x,y,z,c) = min_val;
23032 if (boundary_conditions)
23033 cimg_forYZ(res,y,z)
23034 for (
int x = 0; x<width(); (y<my1 || y>=mye || z<mz1 || z>=mze)?++x:((x<mx1-1 || x>=mxe)?++x:(x=mxe))) {
23036 for (
int zm = -mz1; zm<=mz2; ++zm)
23037 for (
int ym = -my1; ym<=my2; ++ym)
23038 for (
int xm = -mx1; xm<=mx2; ++xm) {
23039 const T cval = (Tt)_img._atXYZ(x+xm,y+ym,z+zm);
23040 if (_mask(mx1+xm,my1+ym,mz1+zm) && cval<min_val) min_val = cval;
23042 res(x,y,z,c) = min_val;
23045 cimg_forYZ(res,y,z)
23046 for (
int x = 0; x<width(); (y<my1 || y>=mye || z<mz1 || z>=mze)?++x:((x<mx1-1 || x>=mxe)?++x:(x=mxe))) {
23048 for (
int zm = -mz1; zm<=mz2; ++zm)
23049 for (
int ym = -my1; ym<=my2; ++ym)
23050 for (
int xm = -mx1; xm<=mx2; ++xm) {
23051 const T cval = (Tt)_img.atXYZ(x+xm,y+ym,z+zm,0,0);
23052 if (_mask(mx1+xm,my1+ym,mz1+zm) && cval<min_val) min_val = cval;
23054 res(x,y,z,c) = min_val;
23067 CImg<T>&
erode(
const unsigned int sx,
const unsigned int sy,
const unsigned int sz=1) {
23068 if (
is_empty() || (sx==1 && sy==1 && sz==1))
return *
this;
23069 if (sx>1 && _width>1) {
23070 const int L =
width(), off = 1, s = (int)sx, _s1 = s/2, _s2 = s - _s1, s1 = _s1>L?L:_s1, s2 = _s2>L?L:_s2;
23072 T *
const ptrdb = buf._data, *ptrd = ptrdb, *
const ptrde = buf._data + L - 1;
23073 cimg_forYZC(*
this,y,z,c) {
23074 const T *
const ptrsb =
data(0,y,z,c), *ptrs = ptrsb, *
const ptrse = ptrs + L*off - off;
23075 ptrd = buf._data; T cur = *ptrs; ptrs+=off;
bool is_first =
true;
23076 for (
int p = s2-1; p>0 && ptrs<=ptrse; --p) {
const T val = *ptrs; ptrs+=off;
if (val<=cur) { cur = val; is_first =
false; }} *(ptrd++) = cur;
23077 for (
int p = s1; p>0 && ptrd<=ptrde; --p) {
const T val = *ptrs;
if (ptrs<ptrse) ptrs+=off;
if (val<=cur) { cur = val; is_first =
false; } *(ptrd++) = cur; }
23078 for (
int p = L - s - 1; p>0; --p) {
23079 const T val = *ptrs; ptrs+=off;
23081 const T *nptrs = ptrs - off; cur = val;
23082 for (
int q = s - 2; q>0; --q) { nptrs-=off;
const T nval = *nptrs;
if (nval<cur) cur = nval; }
23083 nptrs-=off;
const T nval = *nptrs;
if (nval<cur) { cur = nval; is_first =
true; }
else is_first =
false;
23084 }
else {
if (val<=cur) cur = val;
else if (cur==*(ptrs-s*off)) is_first =
true; }
23087 ptrd = ptrde; ptrs = ptrse; cur = *ptrs; ptrs-=off;
23088 for (
int p = s1; p>0 && ptrs>=ptrsb; --p) {
const T val = *ptrs; ptrs-=off;
if (val<cur) cur = val; } *(ptrd--) = cur;
23089 for (
int p = s2-1; p>0 && ptrd>=ptrdb; --p) {
const T val = *ptrs;
if (ptrs>ptrsb) ptrs-=off;
if (val<cur) cur = val; *(ptrd--) = cur; }
23090 T *pd =
data(0,y,z,c); cimg_for(buf,ps,T) { *pd = *ps; pd+=off; }
23094 if (sy>1 && _height>1) {
23095 const int L =
height(), off =
width(), s = (int)sy, _s1 = s/2, _s2 = s - _s1, s1 = _s1>L?L:_s1, s2 = _s2>L?L:_s2;
23097 T *
const ptrdb = buf._data, *ptrd = ptrdb, *
const ptrde = buf._data + L - 1;
23098 cimg_forXZC(*
this,x,z,c) {
23099 const T *
const ptrsb =
data(x,0,z,c), *ptrs = ptrsb, *
const ptrse = ptrs + L*off - off;
23100 ptrd = buf._data; T cur = *ptrs; ptrs+=off;
bool is_first =
true;
23101 for (
int p = s2-1; p>0 && ptrs<=ptrse; --p) {
const T val = *ptrs; ptrs+=off;
if (val<=cur) { cur = val; is_first =
false; }} *(ptrd++) = cur;
23102 for (
int p = s1; p>0 && ptrd<=ptrde; --p) {
const T val = *ptrs;
if (ptrs<ptrse) ptrs+=off;
if (val<=cur) { cur = val; is_first =
false; } *(ptrd++) = cur; }
23103 for (
int p = L - s - 1; p>0; --p) {
23104 const T val = *ptrs; ptrs+=off;
23106 const T *nptrs = ptrs - off; cur = val;
23107 for (
int q = s - 2; q>0; --q) { nptrs-=off;
const T nval = *nptrs;
if (nval<cur) cur = nval; }
23108 nptrs-=off;
const T nval = *nptrs;
if (nval<cur) { cur = nval; is_first =
true; }
else is_first =
false;
23109 }
else {
if (val<=cur) cur = val;
else if (cur==*(ptrs-s*off)) is_first =
true; }
23112 ptrd = ptrde; ptrs = ptrse; cur = *ptrs; ptrs-=off;
23113 for (
int p = s1; p>0 && ptrs>=ptrsb; --p) {
const T val = *ptrs; ptrs-=off;
if (val<cur) cur = val; } *(ptrd--) = cur;
23114 for (
int p = s2-1; p>0 && ptrd>=ptrdb; --p) {
const T val = *ptrs;
if (ptrs>ptrsb) ptrs-=off;
if (val<cur) cur = val; *(ptrd--) = cur; }
23115 T *pd =
data(x,0,z,c); cimg_for(buf,ps,T) { *pd = *ps; pd+=off; }
23119 if (sz>1 && _depth>1) {
23120 const int L =
depth(), off =
width()*
height(), s = (int)sz, _s1 = s/2, _s2 = s - _s1, s1 = _s1>L?L:_s1, s2 = _s2>L?L:_s2;
23122 T *
const ptrdb = buf._data, *ptrd = ptrdb, *
const ptrde = buf._data + L - 1;
23123 cimg_forXYC(*
this,x,y,c) {
23124 const T *
const ptrsb =
data(x,y,0,c), *ptrs = ptrsb, *
const ptrse = ptrs + L*off - off;
23125 ptrd = buf._data; T cur = *ptrs; ptrs+=off;
bool is_first =
true;
23126 for (
int p = s2-1; p>0 && ptrs<=ptrse; --p) {
const T val = *ptrs; ptrs+=off;
if (val<=cur) { cur = val; is_first =
false; }} *(ptrd++) = cur;
23127 for (
int p = s1; p>0 && ptrd<=ptrde; --p) {
const T val = *ptrs;
if (ptrs<ptrse) ptrs+=off;
if (val<=cur) { cur = val; is_first =
false; } *(ptrd++) = cur; }
23128 for (
int p = L - s - 1; p>0; --p) {
23129 const T val = *ptrs; ptrs+=off;
23131 const T *nptrs = ptrs - off; cur = val;
23132 for (
int q = s - 2; q>0; --q) { nptrs-=off;
const T nval = *nptrs;
if (nval<cur) cur = nval; }
23133 nptrs-=off;
const T nval = *nptrs;
if (nval<cur) { cur = nval; is_first =
true; }
else is_first =
false;
23134 }
else {
if (val<=cur) cur = val;
else if (cur==*(ptrs-s*off)) is_first =
true; }
23137 ptrd = ptrde; ptrs = ptrse; cur = *ptrs; ptrs-=off;
23138 for (
int p = s1; p>0 && ptrs>=ptrsb; --p) {
const T val = *ptrs; ptrs-=off;
if (val<cur) cur = val; } *(ptrd--) = cur;
23139 for (
int p = s2-1; p>0 && ptrd>=ptrdb; --p) {
const T val = *ptrs;
if (ptrs>ptrsb) ptrs-=off;
if (val<cur) cur = val; *(ptrd--) = cur; }
23140 T *pd =
data(x,y,0,c); cimg_for(buf,ps,T) { *pd = *ps; pd+=off; }
23148 return (+*
this).
erode(sx,sy,sz);
23156 return erode(s,s,s);
23161 return (+*
this).
erode(s);
23170 template<
typename t>
23172 if (
is_empty() || !mask)
return *
this;
23173 return get_dilate(mask,boundary_conditions,is_normalized).move_to(*
this);
23177 template<
typename t>
23179 const bool is_normalized=
false)
const {
23180 if (
is_empty() || !mask)
return *
this;
23181 typedef _cimg_Tt Tt;
23182 CImg<Tt> res(_width,_height,_depth,_spectrum);
23184 mx2 = mask.width()/2, my2 = mask.height()/2, mz2 = mask.depth()/2,
23185 mx1 = mx2 - 1 + (mask.width()%2), my1 = my2 - 1 + (mask.height()%2), mz1 = mz2 - 1 + (mask.depth()%2),
23187 cimg_forC(*
this,c) {
23189 const CImg<t> _mask = mask.get_shared_channel(c%mask._spectrum);
23190 if (is_normalized) {
23191 for (
int z = mz1; z<mze; ++z)
23192 for (
int y = my1; y<mye; ++y)
23193 for (
int x = mx1; x<mxe; ++x) {
23195 for (
int zm = -mz1; zm<=mz2; ++zm)
23196 for (
int ym = -my1; ym<=my2; ++ym)
23197 for (
int xm = -mx1; xm<=mx2; ++xm) {
23198 const t mval = _mask(mx1+xm,my1+ym,mz1+zm);
23199 const Tt cval = (Tt)(_img(x+xm,y+ym,z+zm) - mval);
23200 if (mval && cval>max_val) max_val = cval;
23202 res(x,y,z,c) = max_val;
23204 if (boundary_conditions)
23205 cimg_forYZ(res,y,z)
23206 for (
int x = 0; x<width(); (y<my1 || y>=mye || z<mz1 || z>=mze)?++x:((x<mx1-1 || x>=mxe)?++x:(x=mxe))) {
23208 for (
int zm = -mz1; zm<=mz2; ++zm)
23209 for (
int ym = -my1; ym<=my2; ++ym)
23210 for (
int xm = -mx1; xm<=mx2; ++xm) {
23211 const t mval = _mask(mx1+xm,my1+ym,mz1+zm);
23212 const Tt cval = (Tt)(_img._atXYZ(x+xm,y+ym,z+zm) - mval);
23213 if (mval && cval>max_val) max_val = cval;
23215 res(x,y,z,c) = max_val;
23218 cimg_forYZ(*
this,y,z)
23219 for (
int x = 0; x<width(); (y<my1 || y>=mye || z<mz1 || z>=mze)?++x:((x<mx1-1 || x>=mxe)?++x:(x=mxe))) {
23221 for (
int zm = -mz1; zm<=mz2; ++zm)
23222 for (
int ym = -my1; ym<=my2; ++ym)
23223 for (
int xm = -mx1; xm<=mx2; ++xm) {
23224 const t mval = _mask(mx1+xm,my1+ym,mz1+zm);
23225 const Tt cval = (Tt)(_img.atXYZ(x+xm,y+ym,z+zm,0,0) - mval);
23226 if (mval && cval>max_val) max_val = cval;
23228 res(x,y,z,c) = max_val;
23231 for (
int z = mz1; z<mze; ++z)
23232 for (
int y = my1; y<mye; ++y)
23233 for (
int x = mx1; x<mxe; ++x) {
23235 for (
int zm = -mz1; zm<=mz2; ++zm)
23236 for (
int ym = -my1; ym<=my2; ++ym)
23237 for (
int xm = -mx1; xm<=mx2; ++xm) {
23238 const Tt cval = (Tt)_img(x+xm,y+ym,z+zm);
23239 if (_mask(mx1+xm,my1+ym,mz1+zm) && cval>max_val) max_val = cval;
23241 res(x,y,z,c) = max_val;
23243 if (boundary_conditions)
23244 cimg_forYZ(res,y,z)
23245 for (
int x = 0; x<width(); (y<my1 || y>=mye || z<mz1 || z>=mze)?++x:((x<mx1-1 || x>=mxe)?++x:(x=mxe))) {
23247 for (
int zm = -mz1; zm<=mz2; ++zm)
23248 for (
int ym = -my1; ym<=my2; ++ym)
23249 for (
int xm = -mx1; xm<=mx2; ++xm) {
23250 const T cval = (Tt)_img._atXYZ(x+xm,y+ym,z+zm);
23251 if (_mask(mx1+xm,my1+ym,mz1+zm) && cval>max_val) max_val = cval;
23253 res(x,y,z,c) = max_val;
23256 cimg_forYZ(res,y,z)
23257 for (
int x = 0; x<width(); (y<my1 || y>=mye || z<mz1 || z>=mze)?++x:((x<mx1-1 || x>=mxe)?++x:(x=mxe))) {
23259 for (
int zm = -mz1; zm<=mz2; ++zm)
23260 for (
int ym = -my1; ym<=my2; ++ym)
23261 for (
int xm = -mx1; xm<=mx2; ++xm) {
23262 const T cval = (Tt)_img.atXYZ(x+xm,y+ym,z+zm,0,0);
23263 if (_mask(mx1+xm,my1+ym,mz1+zm) && cval>max_val) max_val = cval;
23265 res(x,y,z,c) = max_val;
23278 CImg<T>&
dilate(
const unsigned int sx,
const unsigned int sy,
const unsigned int sz=1) {
23279 if (
is_empty() || (sx==1 && sy==1 && sz==1))
return *
this;
23280 if (sx>1 && _width>1) {
23281 const int L =
width(), off = 1, s = (int)sx, _s2 = s/2 + 1, _s1 = s - _s2, s1 = _s1>L?L:_s1, s2 = _s2>L?L:_s2;
23283 T *
const ptrdb = buf._data, *ptrd = ptrdb, *
const ptrde = buf._data + L - 1;
23284 cimg_forYZC(*
this,y,z,c) {
23285 const T *
const ptrsb =
data(0,y,z,c), *ptrs = ptrsb, *
const ptrse = ptrs + L*off - off;
23286 ptrd = buf._data; T cur = *ptrs; ptrs+=off;
bool is_first =
true;
23287 for (
int p = s2-1; p>0 && ptrs<=ptrse; --p) {
const T val = *ptrs; ptrs+=off;
if (val>=cur) { cur = val; is_first =
false; }} *(ptrd++) = cur;
23288 for (
int p = s1; p>0 && ptrd<=ptrde; --p) {
const T val = *ptrs;
if (ptrs<ptrse) ptrs+=off;
if (val>=cur) { cur = val; is_first =
false; } *(ptrd++) = cur; }
23289 for (
int p = L - s - 1; p>0; --p) {
23290 const T val = *ptrs; ptrs+=off;
23292 const T *nptrs = ptrs - off; cur = val;
23293 for (
int q = s - 2; q>0; --q) { nptrs-=off;
const T nval = *nptrs;
if (nval>cur) cur = nval; }
23294 nptrs-=off;
const T nval = *nptrs;
if (nval>cur) { cur = nval; is_first =
true; }
else is_first =
false;
23295 }
else {
if (val>=cur) cur = val;
else if (cur==*(ptrs-s*off)) is_first =
true; }
23298 ptrd = ptrde; ptrs = ptrse; cur = *ptrs; ptrs-=off;
23299 for (
int p = s1; p>0 && ptrs>=ptrsb; --p) {
const T val = *ptrs; ptrs-=off;
if (val>cur) cur = val; } *(ptrd--) = cur;
23300 for (
int p = s2-1; p>0 && ptrd>=ptrdb; --p) {
const T val = *ptrs;
if (ptrs>ptrsb) ptrs-=off;
if (val>cur) cur = val; *(ptrd--) = cur; }
23301 T *pd =
data(0,y,z,c); cimg_for(buf,ps,T) { *pd = *ps; pd+=off; }
23305 if (sy>1 && _height>1) {
23306 const int L =
height(), off =
width(), s = (int)sy, _s2 = s/2 + 1, _s1 = s - _s2, s1 = _s1>L?L:_s1, s2 = _s2>L?L:_s2;
23308 T *
const ptrdb = buf._data, *ptrd = ptrdb, *
const ptrde = buf._data + L - 1;
23309 cimg_forXZC(*
this,x,z,c) {
23310 const T *
const ptrsb =
data(x,0,z,c), *ptrs = ptrsb, *
const ptrse = ptrs + L*off - off;
23311 ptrd = buf._data; T cur = *ptrs; ptrs+=off;
bool is_first =
true;
23312 for (
int p = s2-1; p>0 && ptrs<=ptrse; --p) {
const T val = *ptrs; ptrs+=off;
if (val>=cur) { cur = val; is_first =
false; }} *(ptrd++) = cur;
23313 for (
int p = s1; p>0 && ptrd<=ptrde; --p) {
const T val = *ptrs;
if (ptrs<ptrse) ptrs+=off;
if (val>=cur) { cur = val; is_first =
false; } *(ptrd++) = cur; }
23314 for (
int p = L - s - 1; p>0; --p) {
23315 const T val = *ptrs; ptrs+=off;
23317 const T *nptrs = ptrs - off; cur = val;
23318 for (
int q = s - 2; q>0; --q) { nptrs-=off;
const T nval = *nptrs;
if (nval>cur) cur = nval; }
23319 nptrs-=off;
const T nval = *nptrs;
if (nval>cur) { cur = nval; is_first =
true; }
else is_first =
false;
23320 }
else {
if (val>=cur) cur = val;
else if (cur==*(ptrs-s*off)) is_first =
true; }
23323 ptrd = ptrde; ptrs = ptrse; cur = *ptrs; ptrs-=off;
23324 for (
int p = s1; p>0 && ptrs>=ptrsb; --p) {
const T val = *ptrs; ptrs-=off;
if (val>cur) cur = val; } *(ptrd--) = cur;
23325 for (
int p = s2-1; p>0 && ptrd>=ptrdb; --p) {
const T val = *ptrs;
if (ptrs>ptrsb) ptrs-=off;
if (val>cur) cur = val; *(ptrd--) = cur; }
23326 T *pd =
data(x,0,z,c); cimg_for(buf,ps,T) { *pd = *ps; pd+=off; }
23330 if (sz>1 && _depth>1) {
23331 const int L =
depth(), off =
width()*
height(), s = (int)sz, _s2 = s/2 + 1, _s1 = s - _s2, s1 = _s1>L?L:_s1, s2 = _s2>L?L:_s2;
23333 T *
const ptrdb = buf._data, *ptrd = ptrdb, *
const ptrde = buf._data + L - 1;
23334 cimg_forXYC(*
this,x,y,c) {
23335 const T *
const ptrsb =
data(x,y,0,c), *ptrs = ptrsb, *
const ptrse = ptrs + L*off - off;
23336 ptrd = buf._data; T cur = *ptrs; ptrs+=off;
bool is_first =
true;
23337 for (
int p = s2-1; p>0 && ptrs<=ptrse; --p) {
const T val = *ptrs; ptrs+=off;
if (val>=cur) { cur = val; is_first =
false; }} *(ptrd++) = cur;
23338 for (
int p = s1; p>0 && ptrd<=ptrde; --p) {
const T val = *ptrs;
if (ptrs<ptrse) ptrs+=off;
if (val>=cur) { cur = val; is_first =
false; } *(ptrd++) = cur; }
23339 for (
int p = L - s - 1; p>0; --p) {
23340 const T val = *ptrs; ptrs+=off;
23342 const T *nptrs = ptrs - off; cur = val;
23343 for (
int q = s - 2; q>0; --q) { nptrs-=off;
const T nval = *nptrs;
if (nval>cur) cur = nval; }
23344 nptrs-=off;
const T nval = *nptrs;
if (nval>cur) { cur = nval; is_first =
true; }
else is_first =
false;
23345 }
else {
if (val>=cur) cur = val;
else if (cur==*(ptrs-s*off)) is_first =
true; }
23348 ptrd = ptrde; ptrs = ptrse; cur = *ptrs; ptrs-=off;
23349 for (
int p = s1; p>0 && ptrs>=ptrsb; --p) {
const T val = *ptrs; ptrs-=off;
if (val>cur) cur = val; } *(ptrd--) = cur;
23350 for (
int p = s2-1; p>0 && ptrd>=ptrdb; --p) {
const T val = *ptrs;
if (ptrs>ptrsb) ptrs-=off;
if (val>cur) cur = val; *(ptrd--) = cur; }
23351 T *pd =
data(x,y,0,c); cimg_for(buf,ps,T) { *pd = *ps; pd+=off; }
23359 return (+*
this).
dilate(sx,sy,sz);
23372 return (+*
this).
dilate(s);
23381 template<
typename t>
23386 "watershed(): image instance and specified priority (%u,%u,%u,%u,%p) have different dimensions.",
23387 cimg_instance,priority._width,priority._height,priority._depth,priority._spectrum,priority._data);
23388 if (_spectrum!=1) { cimg_forC(*
this,c)
get_shared_channel(c).watershed(priority.get_shared_channel(c%priority._spectrum),fill_lines);
return *
this; }
23392 unsigned int sizeQ = 0;
23395 const T *ptrs = _data;
23396 cimg_forXYZ(*
this,x,y,z)
if (*(ptrs++)) {
23397 if (x-1>=0 && !(*
this)(x-1,y,z)) Q._priority_queue_insert(in_queue,sizeQ,priority(x-1,y,z),x-1,y,z);
23398 if (x+1<
width() && !(*
this)(x+1,y,z)) Q._priority_queue_insert(in_queue,sizeQ,priority(x+1,y,z),x+1,y,z);
23399 if (y-1>=0 && !(*
this)(x,y-1,z)) Q._priority_queue_insert(in_queue,sizeQ,priority(x,y-1,z),x,y-1,z);
23400 if (y+1<
height() && !(*
this)(x,y+1,z)) Q._priority_queue_insert(in_queue,sizeQ,priority(x,y+1,z),x,y+1,z);
23401 if (z-1>=0 && !(*
this)(x,y,z-1)) Q._priority_queue_insert(in_queue,sizeQ,priority(x,y,z-1),x,y,z-1);
23402 if (z+1<
depth() && !(*
this)(x,y,z+1)) Q._priority_queue_insert(in_queue,sizeQ,priority(x,y,z+1),x,y,z+1);
23409 const int x = (int)Q(0,1), y = (int)Q(0,2), z = (int)Q(0,3);
23410 Q._priority_queue_remove(sizeQ);
23413 bool is_same_label =
true;
23414 unsigned int label = 0;
23416 if ((*
this)(x-1,y,z)) {
if (!label) label = (
unsigned int)(*
this)(x-1,y,z);
else if (label!=(*
this)(x-1,y,z)) is_same_label =
false; }
23417 else Q._priority_queue_insert(in_queue,sizeQ,priority(x-1,y,z),x-1,y,z);
23420 if ((*
this)(x+1,y,z)) {
if (!label) label = (
unsigned int)(*
this)(x+1,y,z);
else if (label!=(*
this)(x+1,y,z)) is_same_label =
false; }
23421 else Q._priority_queue_insert(in_queue,sizeQ,priority(x+1,y,z),x+1,y,z);
23424 if ((*
this)(x,y-1,z)) {
if (!label) label = (
unsigned int)(*
this)(x,y-1,z);
else if (label!=(*
this)(x,y-1,z)) is_same_label =
false; }
23425 else Q._priority_queue_insert(in_queue,sizeQ,priority(x,y-1,z),x,y-1,z);
23428 if ((*
this)(x,y+1,z)) {
if (!label) label = (
unsigned int)(*
this)(x,y+1,z);
else if (label!=(*
this)(x,y+1,z)) is_same_label =
false; }
23429 else Q._priority_queue_insert(in_queue,sizeQ,priority(x,y+1,z),x,y+1,z);
23432 if ((*
this)(x,y,z-1)) {
if (!label) label = (
unsigned int)(*
this)(x,y,z-1);
else if (label!=(*
this)(x,y,z-1)) is_same_label =
false; }
23433 else Q._priority_queue_insert(in_queue,sizeQ,priority(x,y,z-1),x,y,z-1);
23436 if ((*
this)(x,y,z+1)) {
if (!label) label = (
unsigned int)(*
this)(x,y,z+1);
else if (label!=(*
this)(x,y,z+1)) is_same_label =
false; }
23437 else Q._priority_queue_insert(in_queue,sizeQ,priority(x,y,z+1),x,y,z+1);
23439 if (is_same_label) (*this)(x,y,z) = label;
23447 const T *ptrs = _data;
23448 cimg_forXYZ(*
this,x,y,z)
if (!*(ptrs++) &&
23449 ((x-1>=0 && (*
this)(x-1,y,z)) || (x+1<
width() && (*
this)(x+1,y,z)) ||
23450 (y-1>=0 && (*
this)(x,y-1,z)) || (y+1<
height() && (*
this)(x,y+1,z)) ||
23451 (z-1>=0 && (*
this)(x,y,z-1)) || (z+1>
depth() && (*
this)(x,y,z+1))))
23452 Q._priority_queue_insert(in_queue,sizeQ,priority(x,y,z),x,y,z);
23456 const int x = (int)Q(0,1), y = (int)Q(0,2), z = (int)Q(0,3);
23457 Q._priority_queue_remove(sizeQ);
23459 int xmax = 0, ymax = 0, zmax = 0;
23461 if ((*
this)(x-1,y,z)) {
if (priority(x-1,y,z)>pmax) { pmax = priority(x-1,y,z); xmax = x-1; ymax = y; zmax = z; }}
23462 else Q._priority_queue_insert(in_queue,sizeQ,priority(x-1,y,z),x-1,y,z);
23465 if ((*
this)(x+1,y,z)) {
if (priority(x+1,y,z)>pmax) { pmax = priority(x+1,y,z); xmax = x+1; ymax = y; zmax = z; }}
23466 else Q._priority_queue_insert(in_queue,sizeQ,priority(x+1,y,z),x+1,y,z);
23469 if ((*
this)(x,y-1,z)) {
if (priority(x,y-1,z)>pmax) { pmax = priority(x,y-1,z); xmax = x; ymax = y-1; zmax = z; }}
23470 else Q._priority_queue_insert(in_queue,sizeQ,priority(x,y-1,z),x,y-1,z);
23473 if ((*
this)(x,y+1,z)) {
if (priority(x,y+1,z)>pmax) { pmax = priority(x,y+1,z); xmax = x; ymax = y+1; zmax = z; }}
23474 else Q._priority_queue_insert(in_queue,sizeQ,priority(x,y+1,z),x,y+1,z);
23477 if ((*
this)(x,y,z-1)) {
if (priority(x,y,z-1)>pmax) { pmax = priority(x,y,z-1); xmax = x; ymax = y; zmax = z-1; }}
23478 else Q._priority_queue_insert(in_queue,sizeQ,priority(x,y,z-1),x,y,z-1);
23481 if ((*
this)(x,y,z+1)) {
if (priority(x,y,z+1)>pmax) { pmax = priority(x,y,z+1); xmax = x; ymax = y; zmax = z+1; }}
23482 else Q._priority_queue_insert(in_queue,sizeQ,priority(x,y,z+1),x,y,z+1);
23484 (*this)(x,y,z) = (*
this)(xmax,ymax,zmax);
23491 template<
typename t>
23493 return (+*
this).
watershed(priority,fill_lines);
23497 template<
typename t>
23498 bool _priority_queue_insert(
CImg<boolT>& in_queue,
unsigned int& siz,
const t value,
const unsigned int x,
const unsigned int y,
const unsigned int z) {
23499 if (in_queue(x,y,z))
return false;
23500 in_queue(x,y,z) =
true;
23502 (*this)(siz-1,0) = (T)value; (*this)(siz-1,1) = (T)x; (*this)(siz-1,2) = (T)y; (*this)(siz-1,3) = (T)z;
23503 for (
unsigned int pos = siz - 1, par = 0; pos && value>(*this)(par=(pos+1)/2-1,0); pos = par) {
23510 CImg<T>& _priority_queue_remove(
unsigned int& siz) {
23511 (*this)(0,0) = (*
this)(--siz,0); (*this)(0,1) = (*
this)(siz,1); (*this)(0,2) = (*
this)(siz,2); (*this)(0,3) = (*
this)(siz,3);
23512 const float value = (*this)(0,0);
23513 for (
unsigned int pos = 0, left = 0, right = 0;
23514 ((right=2*(pos+1),(left=right-1))<siz && value<(*
this)(left,0)) || (right<siz && value<(*this)(right,0));) {
23516 if ((*
this)(left,0)>(*
this)(right,0)) {
23541 CImg<T>&
deriche(
const float sigma,
const int order=0,
const char axis=
'x',
const bool boundary_conditions=
true) {
23542 #define _cimg_deriche_apply \
23543 Tfloat *ptrY = Y._data, yb = 0, yp = 0; \
23545 if (boundary_conditions) { xp = *ptrX; yb = yp = (Tfloat)(coefp*xp); } \
23546 for (int m = 0; m<N; ++m) { \
23547 const T xc = *ptrX; ptrX+=off; \
23548 const Tfloat yc = *(ptrY++) = (Tfloat)(a0*xc + a1*xp - b1*yp - b2*yb); \
23549 xp = xc; yb = yp; yp = yc; \
23551 T xn = (T)0, xa = (T)0; \
23552 Tfloat yn = 0, ya = 0; \
23553 if (boundary_conditions) { xn = xa = *(ptrX-off); yn = ya = (Tfloat)coefn*xn; } \
23554 for (int n = N-1; n>=0; --n) { \
23555 const T xc = *(ptrX-=off); \
23556 const Tfloat yc = (Tfloat)(a2*xn + a3*xa - b1*yn - b2*ya); \
23557 xa = xn; xn = xc; ya = yn; yn = yc; \
23558 *ptrX = (T)(*(--ptrY)+yc); \
23561 const float nsigma = sigma>=0?sigma:-sigma*(naxis==
'x'?_width:naxis==
'y'?_height:naxis==
'z'?_depth:_spectrum)/100;
23562 if (
is_empty() || (nsigma<0.1 && !order))
return *
this;
23564 nnsigma = nsigma<0.1f?0.1f:nsigma,
23565 alpha = 1.695f/nnsigma,
23566 ema = (float)std::exp(-alpha),
23567 ema2 = (float)std::exp(-2*alpha),
23570 float a0 = 0, a1 = 0, a2 = 0, a3 = 0, coefp = 0, coefn = 0;
23573 const float k = (1-ema)*(1-ema)/(1+2*alpha*ema-ema2);
23575 a1 = k*(alpha-1)*ema;
23576 a2 = k*(alpha+1)*ema;
23580 const float k = -(1-ema)*(1-ema)*(1-ema)/(2*(ema+1)*ema);
23587 ea = (float)std::exp(-alpha),
23588 k = -(ema2-1)/(2*alpha*ema),
23589 kn = (-2*(-1+3*ea-3*ea*ea+ea*ea*ea)/(3*ea+1+3*ea*ea+ea*ea*ea));
23591 a1 = -kn*(1+k*alpha)*ema;
23592 a2 = kn*(1-k*alpha)*ema;
23597 "deriche(): Invalid specified filter order %u "
23598 "(should be { 0=smoothing | 1=1st-derivative | 2=2nd-derivative }).",
23602 coefp = (a0+a1)/(1+b1+b2);
23603 coefn = (a2+a3)/(1+b1+b2);
23606 const int N = _width;
23607 const unsigned long off = 1U;
23609 cimg_forYZC(*
this,y,z,c) { T *ptrX =
data(0,y,z,c); _cimg_deriche_apply; }
23612 const int N = _height;
23613 const unsigned long off = (
unsigned long)_width;
23615 cimg_forXZC(*
this,x,z,c) { T *ptrX =
data(x,0,z,c); _cimg_deriche_apply; }
23618 const int N = _depth;
23619 const unsigned long off = (
unsigned long)_width*_height;
23621 cimg_forXYC(*
this,x,y,c) { T *ptrX =
data(x,y,0,c); _cimg_deriche_apply; }
23624 const int N = _spectrum;
23625 const unsigned long off = (
unsigned long)_width*_height*_depth;
23627 cimg_forXYZ(*
this,x,y,z) { T *ptrX =
data(x,y,z,0); _cimg_deriche_apply; }
23648 CImg<T>&
blur(
const float sigma_x,
const float sigma_y,
const float sigma_z,
const bool boundary_conditions=
true) {
23650 if (_width>1)
deriche(sigma_x,0,
'x',boundary_conditions);
23651 if (_height>1)
deriche(sigma_y,0,
'y',boundary_conditions);
23652 if (_depth>1)
deriche(sigma_z,0,
'z',boundary_conditions);
23658 CImg<Tfloat> get_blur(
const float sigma_x,
const float sigma_y,
const float sigma_z,
const bool boundary_conditions=
true)
const {
23659 return CImg<Tfloat>(*
this,
false).
blur(sigma_x,sigma_y,sigma_z,boundary_conditions);
23668 const float nsigma = sigma>=0?sigma:-sigma*
cimg::max(_width,_height,_depth)/100;
23669 return blur(nsigma,nsigma,nsigma,boundary_conditions);
23687 template<
typename t>
23689 const float amplitude=60,
const float dl=0.8f,
const float da=30,
23690 const float gauss_prec=2,
const unsigned int interpolation_type=0,
23691 const bool is_fast_approx=1) {
23694 if (!
is_sameXYZ(G) || (G._spectrum!=3 && G._spectrum!=6))
23696 "blur_anisotropic(): Invalid specified diffusion tensor field (%u,%u,%u,%u,%p).",
23698 G._width,G._height,G._depth,G._spectrum,G._data);
23700 if (
is_empty() || amplitude<=0 || dl<0)
return *
this;
23701 const bool is_3d = (G._spectrum==6);
23702 T val_min, val_max =
max_min(val_min);
23705 CImg<Tfloat> velocity(_width,_height,_depth,_spectrum);
23706 for (
unsigned int iteration = 0; iteration<(
unsigned int)amplitude; ++iteration) {
23707 Tfloat *ptrd = velocity._data, veloc_max = 0;
23709 CImg_3x3x3(I,Tfloat);
23710 cimg_forC(*
this,c) cimg_for3x3x3(*
this,x,y,z,c,I,Tfloat) {
23712 ixx = Incc + Ipcc - 2*Iccc,
23713 ixy = (Innc + Ippc - Inpc - Ipnc)/4,
23714 ixz = (Incn + Ipcp - Incp - Ipcn)/4,
23715 iyy = Icnc + Icpc - 2*Iccc,
23716 iyz = (Icnn + Icpp - Icnp - Icpn)/4,
23717 izz = Iccn + Iccp - 2*Iccc,
23718 veloc = (Tfloat)(G(x,y,z,0)*ixx + 2*G(x,y,z,1)*ixy + 2*G(x,y,z,2)*ixz + G(x,y,z,3)*iyy + 2*G(x,y,z,4)*iyz + G(x,y,z,5)*izz);
23720 if (veloc>veloc_max) veloc_max = veloc;
else if (-veloc>veloc_max) veloc_max = -veloc;
23723 CImg_3x3(I,Tfloat);
23724 cimg_forZC(*
this,z,c) cimg_for3x3(*
this,x,y,z,c,I,Tfloat) {
23726 ixx = Inc + Ipc - 2*Icc,
23727 ixy = (Inn + Ipp - Inp - Ipn)/4,
23728 iyy = Icn + Icp - 2*Icc,
23729 veloc = (Tfloat)(G(x,y,0,0)*ixx + 2*G(x,y,0,1)*ixy + G(x,y,0,2)*iyy);
23731 if (veloc>veloc_max) veloc_max = veloc;
else if (-veloc>veloc_max) veloc_max = -veloc;
23734 if (veloc_max>0) *
this+=(velocity*=dl/veloc_max);
23737 const unsigned long whd = (
unsigned long)_width*_height*_depth;
23738 const float sqrt2amplitude = (float)std::sqrt(2*amplitude);
23740 CImg<Tfloat> res(_width,_height,_depth,_spectrum,0), W(_width,_height,_depth,is_3d?4:3), val(_spectrum);
23743 for (
float phi = (180%(
int)da)/2.0f; phi<=180; phi+=da) {
23744 const float phir = (float)(phi*
cimg::PI/180), datmp = (float)(da/std::cos(phir)), da2 = datmp<1?360.0f:datmp;
23745 for (
float theta = 0; theta<360; (theta+=da2),++N) {
23747 thetar = (float)(theta*
cimg::PI/180),
23748 vx = (float)(std::cos(thetar)*std::cos(phir)),
23749 vy = (
float)(std::sin(thetar)*std::cos(phir)),
23750 vz = (
float)std::sin(phir);
23752 *pa = G.data(0,0,0,0), *pb = G.data(0,0,0,1), *pc = G.data(0,0,0,2),
23753 *pd = G.data(0,0,0,3), *pe = G.data(0,0,0,4), *pf = G.data(0,0,0,5);
23754 Tfloat *pd0 = W.data(0,0,0,0), *pd1 = W.data(0,0,0,1), *pd2 = W.data(0,0,0,2), *pd3 = W.data(0,0,0,3);
23755 cimg_forXYZ(G,xg,yg,zg) {
23756 const t a = *(pa++), b = *(pb++), c = *(pc++), d = *(pd++), e = *(pe++), f = *(pf++);
23758 u = (float)(a*vx + b*vy + c*vz),
23759 v = (float)(b*vx + d*vy + e*vz),
23760 w = (float)(c*vx + e*vy + f*vz),
23761 n = (float)std::sqrt(1e-5+u*u+v*v+w*w),
23763 *(pd0++) = (Tfloat)(u*dln);
23764 *(pd1++) = (Tfloat)(v*dln);
23765 *(pd2++) = (Tfloat)(w*dln);
23766 *(pd3++) = (Tfloat)n;
23769 Tfloat *ptrd = res._data;
23770 cimg_forXYZ(*
this,x,y,z) {
23773 n = (float)W(x,y,z,3),
23774 fsigma = (float)(n*sqrt2amplitude),
23775 fsigma2 = 2*fsigma*fsigma,
23776 length = gauss_prec*fsigma;
23782 switch (interpolation_type) {
23784 for (
float l = 0; l<length && X>=0 && X<=dx1 && Y>=0 && Y<=dy1 && Z>=0 && Z<=dz1; l+=dl) {
23786 cx = (int)(X+0.5f),
23787 cy = (int)(Y+0.5f),
23788 cz = (int)(Z+0.5f);
23790 u = (float)W(cx,cy,cz,0),
23791 v = (float)W(cx,cy,cz,1),
23792 w = (float)W(cx,cy,cz,2);
23793 if (is_fast_approx) { cimg_forC(*
this,c) val[c]+=(Tfloat)(*
this)(cx,cy,cz,c); ++S; }
23795 const float coef = (float)std::exp(-l*l/fsigma2);
23796 cimg_forC(*
this,c) val[c]+=(Tfloat)(coef*(*
this)(cx,cy,cz,c));
23803 for (
float l = 0; l<length && X>=0 && X<=dx1 && Y>=0 && Y<=dy1 && Z>=0 && Z<=dz1; l+=dl) {
23805 u = (float)(W._linear_atXYZ(X,Y,Z,0)),
23806 v = (
float)(W._linear_atXYZ(X,Y,Z,1)),
23807 w = (
float)(W._linear_atXYZ(X,Y,Z,2));
23808 if (is_fast_approx) { cimg_forC(*
this,c) val[c]+=(Tfloat)_linear_atXYZ(X,Y,Z,c); ++S; }
23810 const float coef = (float)std::exp(-l*l/fsigma2);
23811 cimg_forC(*
this,c) val[c]+=(Tfloat)(coef*_linear_atXYZ(X,Y,Z,c));
23818 for (
float l = 0; l<length && X>=0 && X<=dx1 && Y>=0 && Y<=dy1 && Z>=0 && Z<=dz1; l+=dl) {
23820 u0 = (float)(0.5f*W._linear_atXYZ(X,Y,Z,0)),
23821 v0 = (
float)(0.5f*W._linear_atXYZ(X,Y,Z,1)),
23822 w0 = (
float)(0.5f*W._linear_atXYZ(X,Y,Z,2)),
23823 u = (
float)(W._linear_atXYZ(X+u0,Y+v0,Z+w0,0)),
23824 v = (
float)(W._linear_atXYZ(X+u0,Y+v0,Z+w0,1)),
23825 w = (
float)(W._linear_atXYZ(X+u0,Y+v0,Z+w0,2));
23826 if (is_fast_approx) { cimg_forC(*
this,c) val[c]+=(Tfloat)_linear_atXYZ(X,Y,Z,c); ++S; }
23828 const float coef = (float)std::exp(-l*l/fsigma2);
23829 cimg_forC(*
this,c) val[c]+=(Tfloat)(coef*_linear_atXYZ(X,Y,Z,c));
23836 Tfloat *_ptrd = ptrd++;
23837 if (S>0) cimg_forC(res,c) { *_ptrd+=val[c]/S; _ptrd+=whd; }
23838 else cimg_forC(res,c) { *_ptrd+=(Tfloat)((*
this)(x,y,z,c)); _ptrd+=whd; }
23843 for (
float theta = (360%(
int)da)/2.0f; theta<360; (theta+=da),++N) {
23844 const float thetar = (float)(theta*
cimg::PI/180), vx = (float)(std::cos(thetar)), vy = (
float)(std::sin(thetar));
23845 const t *pa = G.data(0,0,0,0), *pb = G.data(0,0,0,1), *pc = G.data(0,0,0,2);
23846 Tfloat *pd0 = W.data(0,0,0,0), *pd1 = W.data(0,0,0,1), *pd2 = W.data(0,0,0,2);
23847 cimg_forXY(G,xg,yg) {
23848 const t a = *(pa++), b = *(pb++), c = *(pc++);
23850 u = (float)(a*vx + b*vy),
23851 v = (float)(b*vx + c*vy),
23852 n = (float)std::sqrt(1e-5+u*u+v*v),
23854 *(pd0++) = (Tfloat)(u*dln);
23855 *(pd1++) = (Tfloat)(v*dln);
23856 *(pd2++) = (Tfloat)n;
23858 Tfloat *ptrd = res._data;
23859 cimg_forXY(*
this,x,y) {
23862 n = (float)W(x,y,0,2),
23863 fsigma = (float)(n*sqrt2amplitude),
23864 fsigma2 = 2*fsigma*fsigma,
23865 length = gauss_prec*fsigma;
23870 switch (interpolation_type) {
23872 for (
float l = 0; l<length && X>=0 && X<=dx1 && Y>=0 && Y<=dy1; l+=dl) {
23874 cx = (int)(X+0.5f),
23875 cy = (int)(Y+0.5f);
23877 u = (float)W(cx,cy,0,0),
23878 v = (float)W(cx,cy,0,1);
23879 if (is_fast_approx) { cimg_forC(*
this,c) val[c]+=(Tfloat)(*
this)(cx,cy,0,c); ++S; }
23881 const float coef = (float)std::exp(-l*l/fsigma2);
23882 cimg_forC(*
this,c) val[c]+=(Tfloat)(coef*(*
this)(cx,cy,0,c));
23889 for (
float l = 0; l<length && X>=0 && X<=dx1 && Y>=0 && Y<=dy1; l+=dl) {
23891 u = (float)(W._linear_atXY(X,Y,0,0)),
23892 v = (
float)(W._linear_atXY(X,Y,0,1));
23893 if (is_fast_approx) { cimg_forC(*
this,c) val[c]+=(Tfloat)_linear_atXY(X,Y,0,c); ++S; }
23895 const float coef = (float)std::exp(-l*l/fsigma2);
23896 cimg_forC(*
this,c) val[c]+=(Tfloat)(coef*_linear_atXY(X,Y,0,c));
23903 for (
float l = 0; l<length && X>=0 && X<=dx1 && Y>=0 && Y<=dy1; l+=dl) {
23905 u0 = (float)(0.5f*W._linear_atXY(X,Y,0,0)),
23906 v0 = (
float)(0.5f*W._linear_atXY(X,Y,0,1)),
23907 u = (
float)(W._linear_atXY(X+u0,Y+v0,0,0)),
23908 v = (
float)(W._linear_atXY(X+u0,Y+v0,0,1));
23909 if (is_fast_approx) { cimg_forC(*
this,c) val[c]+=(Tfloat)_linear_atXY(X,Y,0,c); ++S; }
23911 const float coef = (float)std::exp(-l*l/fsigma2);
23912 cimg_forC(*
this,c) val[c]+=(Tfloat)(coef*_linear_atXY(X,Y,0,c));
23919 Tfloat *_ptrd = ptrd++;
23920 if (S>0) cimg_forC(res,c) { *_ptrd+=val[c]/S; _ptrd+=whd; }
23921 else cimg_forC(res,c) { *_ptrd+=(Tfloat)((*
this)(x,y,0,c)); _ptrd+=whd; }
23925 const Tfloat *ptrs = res._data;
23926 cimg_for(*
this,ptrd,T) {
const Tfloat val = *(ptrs++)/N; *ptrd = val<val_min?val_min:(val>val_max?val_max:(T)val); }
23932 template<
typename t>
23934 const float amplitude=60,
const float dl=0.8f,
const float da=30,
23935 const float gauss_prec=2,
const unsigned int interpolation_type=0,
23936 const bool is_fast_approx=
true)
const {
23937 return (+*
this).blur_anisotropic(G,amplitude,dl,da,gauss_prec,interpolation_type,is_fast_approx);
23954 const float alpha=0.6f,
const float sigma=1.1f,
const float dl=0.8f,
const float da=30,
23955 const float gauss_prec=2,
const unsigned int interpolation_type=0,
23956 const bool is_fast_approx=
true) {
23958 amplitude,dl,da,gauss_prec,interpolation_type,is_fast_approx);
23963 const float alpha=0.6f,
const float sigma=1.1f,
const float dl=0.8f,
23964 const float da=30,
const float gauss_prec=2,
const unsigned int interpolation_type=0,
23965 const bool is_fast_approx=
true)
const {
23966 return (+*
this).blur_anisotropic(amplitude,sharpness,anisotropy,alpha,sigma,dl,da,gauss_prec,interpolation_type,is_fast_approx);
23984 const int bgrid_x,
const int bgrid_y,
const int bgrid_z,
const int bgrid_r,
23985 const bool interpolation_type=
true) {
23988 const float range = (float)(1.0f + M - m);
23990 bx0 = bgrid_x>=0?bgrid_x:_width*(-bgrid_x)/100,
23991 by0 = bgrid_y>=0?bgrid_y:_height*(-bgrid_y)/100,
23992 bz0 = bgrid_z>=0?bgrid_z:_depth*(-bgrid_z)/100,
23993 br0 = bgrid_r>=0?bgrid_r:(
int)(-range*bgrid_r/100),
23999 _sigma_x = sigma_x>=0?sigma_x:-sigma_x*_width/100,
24000 _sigma_y = sigma_y>=0?sigma_y:-sigma_y*_height/100,
24001 _sigma_z = sigma_z>=0?sigma_z:-sigma_z*_depth/100,
24002 nsigma_x = _sigma_x*bx/_width,
24003 nsigma_y = _sigma_y*by/_height,
24004 nsigma_z = _sigma_z*bz/_depth,
24005 nsigma_r = sigma_r*br/range;
24006 if (nsigma_x>0 || nsigma_y>0 || nsigma_z>0 || nsigma_r>0) {
24007 const bool is_3d = (_depth>1);
24010 cimg_forC(*
this,c) {
24011 bgrid.fill(0); bgridw.
fill(0);
24012 cimg_forXYZ(*
this,x,y,z) {
24013 const T val = (*this)(x,y,z,c);
24014 const int X = x*bx/_width, Y = y*by/_height, Z = z*bz/_depth, R = (int)((val-m)*br/range);
24015 bgrid(X,Y,Z,R) += (float)val;
24016 bgridw(X,Y,Z,R) += 1;
24018 bgrid.
blur(nsigma_x,nsigma_y,nsigma_z,
true).
deriche(nsigma_r,0,
'c',
false);
24019 bgridw.
blur(nsigma_x,nsigma_y,nsigma_z,
true).
deriche(nsigma_r,0,
'c',
false);
24020 if (interpolation_type) cimg_forXYZ(*
this,x,y,z) {
24021 const T val = (*this)(x,y,z,c);
24022 const float X = (float)x*bx/_width, Y = (
float)y*by/_height, Z = (float)z*bz/_depth, R = (
float)((val-m)*br/range),
24023 bval0 = bgrid._linear_atXYZC(X,Y,Z,R), bval1 = bgridw._linear_atXYZC(X,Y,Z,R);
24024 (*this)(x,y,z,c) = (T)(bval0/bval1);
24025 }
else cimg_forXYZ(*
this,x,y,z) {
24026 const T val = (*this)(x,y,z,c);
24027 const int X = x*bx/_width, Y = y*by/_height, Z = z*bz/_depth, R = (int)((val-m)*br/range);
24028 const float bval0 = bgrid(X,Y,Z,R), bval1 = bgridw(X,Y,Z,R);
24029 (*this)(x,y,z,c) = (T)(bval0/bval1);
24034 cimg_forC(*
this,c) {
24036 cimg_forXY(*
this,x,y) {
24037 const T val = (*this)(x,y,c);
24038 const int X = x*bx/_width, Y = y*by/_height, R = (int)((val-m)*br/range);
24039 bgrid(X,Y,R,0) += (float)val;
24040 bgrid(X,Y,R,1) += 1;
24042 bgrid.
blur(nsigma_x,nsigma_y,0,
true).
blur(0,0,nsigma_r,
false);
24043 if (interpolation_type) cimg_forXY(*
this,x,y) {
24044 const T val = (*this)(x,y,c);
24045 const float X = (float)x*bx/_width, Y = (
float)y*by/_height, R = (float)((val-m)*br/range),
24046 bval0 = bgrid._linear_atXYZ(X,Y,R,0), bval1 = bgrid._linear_atXYZ(X,Y,R,1);
24047 (*this)(x,y,c) = (T)(bval0/bval1);
24048 }
else cimg_forXY(*
this,x,y) {
24049 const T val = (*this)(x,y,c);
24050 const int X = x*bx/_width, Y = y*by/_height, R = (int)((val-m)*br/range);
24051 const float bval0 = bgrid(X,Y,R,0), bval1 = bgrid(X,Y,R,1);
24052 (*this)(x,y,c) = (T)(bval0/bval1);
24062 const int bgrid_x,
const int bgrid_y,
const int bgrid_z,
const int bgrid_r,
24063 const bool interpolation_type=
true)
const {
24064 return (+*
this).blur_bilateral(sigma_x,sigma_y,sigma_z,sigma_r,bgrid_x,bgrid_y,bgrid_z,bgrid_r,interpolation_type);
24076 const bool interpolation_type=
true) {
24077 const float nsigma_s = sigma_s>=0?sigma_s:-sigma_s*
cimg::max(_width,_height,_depth)/100;
24078 return blur_bilateral(nsigma_s,nsigma_s,nsigma_s,sigma_r,bgrid_s,bgrid_s,bgrid_s,bgrid_r,interpolation_type);
24083 const bool interpolation_type=
true)
const {
24084 return (+*
this).blur_bilateral(sigma_s,sigma_s,sigma_s,sigma_r,bgrid_s,bgrid_s,bgrid_s,bgrid_r,interpolation_type);
24097 const unsigned int lookup_size=4,
const float smoothness=0,
const bool is_fast_approx=
true) {
24098 if (
is_empty() || !patch_size || !lookup_size)
return *
this;
24099 return get_blur_patch(sigma_s,sigma_p,patch_size,lookup_size,smoothness,is_fast_approx).move_to(*
this);
24104 const unsigned int lookup_size=4,
const float smoothness=0,
const bool is_fast_approx=
true)
const {
24106 #define _cimg_blur_patch3d_fast(N) \
24107 cimg_for##N##XYZ(res,x,y,z) { \
24108 T *pP = P._data; cimg_forC(res,c) { cimg_get##N##x##N##x##N(img,x,y,z,c,pP,T); pP+=N3; } \
24109 const int x0 = x - rsize1, y0 = y - rsize1, z0 = z - rsize1, x1 = x + rsize2, y1 = y + rsize2, z1 = z + rsize2; \
24110 float sum_weights = 0; \
24111 cimg_for_in##N##XYZ(res,x0,y0,z0,x1,y1,z1,p,q,r) if (cimg::abs(img(x,y,z,0) - img(p,q,r,0))<sigma_p3) { \
24112 T *pQ = Q._data; cimg_forC(res,c) { cimg_get##N##x##N##x##N(img,p,q,r,c,pQ,T); pQ+=N3; } \
24113 float distance2 = 0; \
24114 pQ = Q._data; cimg_for(P,pP,T) { const float dI = (float)*pP - (float)*(pQ++); distance2+=dI*dI; } \
24115 distance2/=Pnorm; \
24116 const float dx = (float)p - x, dy = (float)q - y, dz = (float)r - z, \
24117 alldist = distance2 + (dx*dx + dy*dy + dz*dz)/sigma_s2, weight = alldist>3?0.0f:1.0f; \
24118 sum_weights+=weight; \
24119 cimg_forC(res,c) res(x,y,z,c)+=weight*(*this)(p,q,r,c); \
24121 if (sum_weights>0) cimg_forC(res,c) res(x,y,z,c)/=sum_weights; \
24122 else cimg_forC(res,c) res(x,y,z,c) = (Tfloat)((*this)(x,y,z,c)); \
24125 #define _cimg_blur_patch3d(N) \
24126 cimg_for##N##XYZ(res,x,y,z) { \
24127 T *pP = P._data; cimg_forC(res,c) { cimg_get##N##x##N##x##N(img,x,y,z,c,pP,T); pP+=N3; } \
24128 const int x0 = x - rsize1, y0 = y - rsize1, z0 = z - rsize1, x1 = x + rsize2, y1 = y + rsize2, z1 = z + rsize2; \
24129 float sum_weights = 0, weight_max = 0; \
24130 cimg_for_in##N##XYZ(res,x0,y0,z0,x1,y1,z1,p,q,r) if (p!=x || q!=y || r!=z) { \
24131 T *pQ = Q._data; cimg_forC(res,c) { cimg_get##N##x##N##x##N(img,p,q,r,c,pQ,T); pQ+=N3; } \
24132 float distance2 = 0; \
24133 pQ = Q._data; cimg_for(P,pP,T) { const float dI = (float)*pP - (float)*(pQ++); distance2+=dI*dI; } \
24134 distance2/=Pnorm; \
24135 const float dx = (float)p - x, dy = (float)q - y, dz = (float)r - z, \
24136 alldist = distance2 + (dx*dx + dy*dy + dz*dz)/sigma_s2, weight = (float)std::exp(-alldist); \
24137 if (weight>weight_max) weight_max = weight; \
24138 sum_weights+=weight; \
24139 cimg_forC(res,c) res(x,y,z,c)+=weight*(*this)(p,q,r,c); \
24141 sum_weights+=weight_max; cimg_forC(res,c) res(x,y,z,c)+=weight_max*(*this)(x,y,z,c); \
24142 if (sum_weights>0) cimg_forC(res,c) res(x,y,z,c)/=sum_weights; \
24143 else cimg_forC(res,c) res(x,y,z,c) = (Tfloat)((*this)(x,y,z,c)); \
24146 #define _cimg_blur_patch2d_fast(N) \
24147 cimg_for##N##XY(res,x,y) { \
24148 T *pP = P._data; cimg_forC(res,c) { cimg_get##N##x##N(img,x,y,0,c,pP,T); pP+=N2; } \
24149 const int x0 = x - rsize1, y0 = y - rsize1, x1 = x + rsize2, y1 = y + rsize2; \
24150 float sum_weights = 0; \
24151 cimg_for_in##N##XY(res,x0,y0,x1,y1,p,q) if (cimg::abs(img(x,y,0,0) - img(p,q,0,0))<sigma_p3) { \
24152 T *pQ = Q._data; cimg_forC(res,c) { cimg_get##N##x##N(img,p,q,0,c,pQ,T); pQ+=N2; } \
24153 float distance2 = 0; \
24154 pQ = Q._data; cimg_for(P,pP,T) { const float dI = (float)*pP - (float)*(pQ++); distance2+=dI*dI; } \
24155 distance2/=Pnorm; \
24156 const float dx = (float)p - x, dy = (float)q - y, \
24157 alldist = distance2 + (dx*dx+dy*dy)/sigma_s2, weight = alldist>3?0.0f:1.0f; \
24158 sum_weights+=weight; \
24159 cimg_forC(res,c) res(x,y,c)+=weight*(*this)(p,q,c); \
24161 if (sum_weights>0) cimg_forC(res,c) res(x,y,c)/=sum_weights; \
24162 else cimg_forC(res,c) res(x,y,c) = (Tfloat)((*this)(x,y,c)); \
24165 #define _cimg_blur_patch2d(N) \
24166 cimg_for##N##XY(res,x,y) { \
24167 T *pP = P._data; cimg_forC(res,c) { cimg_get##N##x##N(img,x,y,0,c,pP,T); pP+=N2; } \
24168 const int x0 = x - rsize1, y0 = y - rsize1, x1 = x + rsize2, y1 = y + rsize2; \
24169 float sum_weights = 0, weight_max = 0; \
24170 cimg_for_in##N##XY(res,x0,y0,x1,y1,p,q) if (p!=x || q!=y) { \
24171 T *pQ = Q._data; cimg_forC(res,c) { cimg_get##N##x##N(img,p,q,0,c,pQ,T); pQ+=N2; } \
24172 float distance2 = 0; \
24173 pQ = Q._data; cimg_for(P,pP,T) { const float dI = (float)*pP - (float)*(pQ++); distance2+=dI*dI; } \
24174 distance2/=Pnorm; \
24175 const float dx = (float)p - x, dy = (float)q - y, \
24176 alldist = distance2 + (dx*dx+dy*dy)/sigma_s2, weight = (float)std::exp(-alldist); \
24177 if (weight>weight_max) weight_max = weight; \
24178 sum_weights+=weight; \
24179 cimg_forC(res,c) res(x,y,c)+=weight*(*this)(p,q,c); \
24181 sum_weights+=weight_max; cimg_forC(res,c) res(x,y,c)+=weight_max*(*this)(x,y,c); \
24182 if (sum_weights>0) cimg_forC(res,c) res(x,y,c)/=sum_weights; \
24183 else cimg_forC(res,c) res(x,y,c) = (Tfloat)((*this)(x,y,c)); \
24186 if (
is_empty() || !patch_size || !lookup_size)
return +*
this;
24189 CImg<T> P(patch_size*patch_size*_spectrum), Q(P);
24191 nsigma_s = sigma_s>=0?sigma_s:-sigma_s*
cimg::max(_width,_height,_depth)/100,
24192 sigma_s2 = nsigma_s*nsigma_s, sigma_p2 = sigma_p*sigma_p, sigma_p3 = 3*sigma_p,
24193 Pnorm = P.size()*sigma_p2;
24194 const int rsize2 = (int)lookup_size/2, rsize1 = (
int)lookup_size - rsize2 - 1;
24195 const unsigned int N2 = patch_size*patch_size, N3 = N2*patch_size;
24196 if (_depth>1)
switch (patch_size) {
24197 case 2 :
if (is_fast_approx) _cimg_blur_patch3d_fast(2)
else _cimg_blur_patch3d(2)
break;
24198 case 3 :
if (is_fast_approx) _cimg_blur_patch3d_fast(3)
else _cimg_blur_patch3d(3)
break;
24200 const int psize2 = (int)patch_size/2, psize1 = (
int)patch_size - psize2 - 1;
24201 if (is_fast_approx) cimg_forXYZ(res,x,y,z) {
24202 P = img.get_crop(x - psize1,y - psize1,z - psize1,x + psize2,y + psize2,z + psize2,
true);
24203 const int x0 = x - rsize1, y0 = y - rsize1, z0 = z - rsize1, x1 = x + rsize2, y1 = y + rsize2, z1 = z + rsize2;
24204 float sum_weights = 0;
24205 cimg_for_inXYZ(res,x0,y0,z0,x1,y1,z1,p,q,r)
if (
cimg::abs(img(x,y,z,0)-img(p,q,r,0))<sigma_p3) {
24206 (Q = img.get_crop(p - psize1,q - psize1,r - psize1,p + psize2,q + psize2,r + psize2,
true))-=P;
24208 dx = (float)x - p, dy = (
float)y - q, dz = (float)z - r,
24209 distance2 = (
float)(Q.pow(2).sum()/Pnorm + (dx*dx + dy*dy + dz*dz)/sigma_s2),
24210 weight = distance2>3?0.0f:1.0f;
24211 sum_weights+=weight;
24212 cimg_forC(res,c) res(x,y,z,c)+=weight*(*this)(p,q,r,c);
24214 if (sum_weights>0) cimg_forC(res,c) res(x,y,z,c)/=sum_weights;
24215 else cimg_forC(res,c) res(x,y,z,c) = (Tfloat)((*
this)(x,y,z,c));
24216 }
else cimg_forXYZ(res,x,y,z) {
24217 P = img.get_crop(x - psize1,y - psize1,z - psize1,x + psize2,y + psize2,z + psize2,
true);
24218 const int x0 = x - rsize1, y0 = y - rsize1, z0 = z - rsize1, x1 = x + rsize2, y1 = y + rsize2, z1 = z + rsize2;
24219 float sum_weights = 0, weight_max = 0;
24220 cimg_for_inXYZ(res,x0,y0,z0,x1,y1,z1,p,q,r)
if (p!=x || q!=y || r!=z) {
24221 (Q = img.get_crop(p - psize1,q - psize1,r - psize1,p + psize2,q + psize2,r + psize2,
true))-=P;
24223 dx = (float)x - p, dy = (
float)y - q, dz = (float)z - r,
24224 distance2 = (
float)(Q.pow(2).sum()/Pnorm + (dx*dx + dy*dy + dz*dz)/sigma_s2),
24225 weight = (float)std::exp(-distance2);
24226 if (weight>weight_max) weight_max = weight;
24227 sum_weights+=weight;
24228 cimg_forC(res,c) res(x,y,z,c)+=weight*(*this)(p,q,r,c);
24230 sum_weights+=weight_max; cimg_forC(res,c) res(x,y,z,c)+=weight_max*(*this)(x,y,z,c);
24231 if (sum_weights>0) cimg_forC(res,c) res(x,y,z,c)/=sum_weights;
24232 else cimg_forC(res,c) res(x,y,z,c) = (Tfloat)((*
this)(x,y,z,c));
24235 }
else switch (patch_size) {
24236 case 2 :
if (is_fast_approx) _cimg_blur_patch2d_fast(2)
else _cimg_blur_patch2d(2)
break;
24237 case 3 :
if (is_fast_approx) _cimg_blur_patch2d_fast(3)
else _cimg_blur_patch2d(3)
break;
24238 case 4 :
if (is_fast_approx) _cimg_blur_patch2d_fast(4)
else _cimg_blur_patch2d(4)
break;
24239 case 5 :
if (is_fast_approx) _cimg_blur_patch2d_fast(5)
else _cimg_blur_patch2d(5)
break;
24240 case 6 :
if (is_fast_approx) _cimg_blur_patch2d_fast(6)
else _cimg_blur_patch2d(6)
break;
24241 case 7 :
if (is_fast_approx) _cimg_blur_patch2d_fast(7)
else _cimg_blur_patch2d(7)
break;
24242 case 8 :
if (is_fast_approx) _cimg_blur_patch2d_fast(8)
else _cimg_blur_patch2d(8)
break;
24243 case 9 :
if (is_fast_approx) _cimg_blur_patch2d_fast(9)
else _cimg_blur_patch2d(9)
break;
24245 const int psize2 = (int)patch_size/2, psize1 = (
int)patch_size - psize2 - 1;
24246 if (is_fast_approx) cimg_forXY(res,x,y) {
24247 P = img.get_crop(x - psize1,y - psize1,x + psize2,y + psize2,
true);
24248 const int x0 = x - rsize1, y0 = y - rsize1, x1 = x + rsize2, y1 = y + rsize2;
24249 float sum_weights = 0;
24250 cimg_for_inXY(res,x0,y0,x1,y1,p,q)
if (
cimg::abs(img(x,y,0)-img(p,q,0))<sigma_p3) {
24251 (Q = img.get_crop(p - psize1,q - psize1,p + psize2,q + psize2,
true))-=P;
24253 dx = (float)x - p, dy = (
float)y - q,
24254 distance2 = (float)(Q.pow(2).sum()/Pnorm + (dx*dx + dy*dy)/sigma_s2),
24255 weight = distance2>3?0.0f:1.0f;
24256 sum_weights+=weight;
24257 cimg_forC(res,c) res(x,y,c)+=weight*(*this)(p,q,c);
24259 if (sum_weights>0) cimg_forC(res,c) res(x,y,c)/=sum_weights;
24260 else cimg_forC(res,c) res(x,y,c) = (Tfloat)((*
this)(x,y,c));
24261 }
else cimg_forXY(res,x,y) {
24262 P = img.get_crop(x - psize1,y - psize1,x + psize2,y + psize2,
true);
24263 const int x0 = x - rsize1, y0 = y - rsize1, x1 = x + rsize2, y1 = y + rsize2;
24264 float sum_weights = 0, weight_max = 0;
24265 cimg_for_inXY(res,x0,y0,x1,y1,p,q)
if (p!=x || q!=y) {
24266 (Q = img.get_crop(p - psize1,q - psize1,p + psize2,q + psize2,
true))-=P;
24268 dx = (float)x - p, dy = (
float)y - q,
24269 distance2 = (float)(Q.pow(2).sum()/Pnorm + (dx*dx + dy*dy)/sigma_s2),
24270 weight = (float)std::exp(-distance2);
24271 if (weight>weight_max) weight_max = weight;
24272 sum_weights+=weight;
24273 cimg_forC(res,c) res(x,y,c)+=weight*(*this)(p,q,c);
24275 sum_weights+=weight_max; cimg_forC(res,c) res(x,y,c)+=weight_max*(*this)(x,y,c);
24276 if (sum_weights>0) cimg_forC(res,c) res(x,y,c)/=sum_weights;
24277 else cimg_forC(res,c) res(x,y,0,c) = (Tfloat)((*
this)(x,y,c));
24289 if (!n)
return *
this;
24295 if (
is_empty() || n<=1)
return +*
this;
24296 CImg<T> res(_width,_height,_depth,_spectrum);
24297 T *ptrd = res._data;
24298 const int hl = n/2, hr = hl - 1 + n%2;
24299 if (res._depth!=1) cimg_forXYZC(*
this,x,y,z,c) {
24301 x0 = x - hl, y0 = y - hl, z0 = z-hl, x1 = x + hr, y1 = y + hr, z1 = z+hr,
24302 nx0 = x0<0?0:x0, ny0 = y0<0?0:y0, nz0 = z0<0?0:z0,
24304 *(ptrd++) =
get_crop(nx0,ny0,nz0,c,nx1,ny1,nz1,c).median();
24306 #define _cimg_median_sort(a,b) if ((a)>(b)) cimg::swap(a,b)
24307 if (res._height!=1)
switch (n) {
24311 cimg_forC(*
this,c) cimg_for3x3(*
this,x,y,0,c,I,T) {
24312 std::memcpy(J,I,9*
sizeof(T));
24313 _cimg_median_sort(Jcp, Jnp); _cimg_median_sort(Jcc, Jnc); _cimg_median_sort(Jcn, Jnn);
24314 _cimg_median_sort(Jpp, Jcp); _cimg_median_sort(Jpc, Jcc); _cimg_median_sort(Jpn, Jcn);
24315 _cimg_median_sort(Jcp, Jnp); _cimg_median_sort(Jcc, Jnc); _cimg_median_sort(Jcn, Jnn);
24316 _cimg_median_sort(Jpp, Jpc); _cimg_median_sort(Jnc, Jnn); _cimg_median_sort(Jcc, Jcn);
24317 _cimg_median_sort(Jpc, Jpn); _cimg_median_sort(Jcp, Jcc); _cimg_median_sort(Jnp, Jnc);
24318 _cimg_median_sort(Jcc, Jcn); _cimg_median_sort(Jcc, Jnp); _cimg_median_sort(Jpn, Jcc);
24319 _cimg_median_sort(Jcc, Jnp);
24326 cimg_forC(*
this,c) cimg_for5x5(*
this,x,y,0,c,I,T) {
24327 std::memcpy(J,I,25*
sizeof(T));
24328 _cimg_median_sort(Jbb, Jpb); _cimg_median_sort(Jnb, Jab); _cimg_median_sort(Jcb, Jab); _cimg_median_sort(Jcb, Jnb);
24329 _cimg_median_sort(Jpp, Jcp); _cimg_median_sort(Jbp, Jcp); _cimg_median_sort(Jbp, Jpp); _cimg_median_sort(Jap, Jbc);
24330 _cimg_median_sort(Jnp, Jbc); _cimg_median_sort(Jnp, Jap); _cimg_median_sort(Jcc, Jnc); _cimg_median_sort(Jpc, Jnc);
24331 _cimg_median_sort(Jpc, Jcc); _cimg_median_sort(Jbn, Jpn); _cimg_median_sort(Jac, Jpn); _cimg_median_sort(Jac, Jbn);
24332 _cimg_median_sort(Jnn, Jan); _cimg_median_sort(Jcn, Jan); _cimg_median_sort(Jcn, Jnn); _cimg_median_sort(Jpa, Jca);
24333 _cimg_median_sort(Jba, Jca); _cimg_median_sort(Jba, Jpa); _cimg_median_sort(Jna, Jaa); _cimg_median_sort(Jcb, Jbp);
24334 _cimg_median_sort(Jnb, Jpp); _cimg_median_sort(Jbb, Jpp); _cimg_median_sort(Jbb, Jnb); _cimg_median_sort(Jab, Jcp);
24335 _cimg_median_sort(Jpb, Jcp); _cimg_median_sort(Jpb, Jab); _cimg_median_sort(Jpc, Jac); _cimg_median_sort(Jnp, Jac);
24336 _cimg_median_sort(Jnp, Jpc); _cimg_median_sort(Jcc, Jbn); _cimg_median_sort(Jap, Jbn); _cimg_median_sort(Jap, Jcc);
24337 _cimg_median_sort(Jnc, Jpn); _cimg_median_sort(Jbc, Jpn); _cimg_median_sort(Jbc, Jnc); _cimg_median_sort(Jba, Jna);
24338 _cimg_median_sort(Jcn, Jna); _cimg_median_sort(Jcn, Jba); _cimg_median_sort(Jpa, Jaa); _cimg_median_sort(Jnn, Jaa);
24339 _cimg_median_sort(Jnn, Jpa); _cimg_median_sort(Jan, Jca); _cimg_median_sort(Jnp, Jcn); _cimg_median_sort(Jap, Jnn);
24340 _cimg_median_sort(Jbb, Jnn); _cimg_median_sort(Jbb, Jap); _cimg_median_sort(Jbc, Jan); _cimg_median_sort(Jpb, Jan);
24341 _cimg_median_sort(Jpb, Jbc); _cimg_median_sort(Jpc, Jba); _cimg_median_sort(Jcb, Jba); _cimg_median_sort(Jcb, Jpc);
24342 _cimg_median_sort(Jcc, Jpa); _cimg_median_sort(Jnb, Jpa); _cimg_median_sort(Jnb, Jcc); _cimg_median_sort(Jnc, Jca);
24343 _cimg_median_sort(Jab, Jca); _cimg_median_sort(Jab, Jnc); _cimg_median_sort(Jac, Jna); _cimg_median_sort(Jbp, Jna);
24344 _cimg_median_sort(Jbp, Jac); _cimg_median_sort(Jbn, Jaa); _cimg_median_sort(Jpp, Jaa); _cimg_median_sort(Jpp, Jbn);
24345 _cimg_median_sort(Jcp, Jpn); _cimg_median_sort(Jcp, Jan); _cimg_median_sort(Jnc, Jpa); _cimg_median_sort(Jbn, Jna);
24346 _cimg_median_sort(Jcp, Jnc); _cimg_median_sort(Jcp, Jbn); _cimg_median_sort(Jpb, Jap); _cimg_median_sort(Jnb, Jpc);
24347 _cimg_median_sort(Jbp, Jcn); _cimg_median_sort(Jpc, Jcn); _cimg_median_sort(Jap, Jcn); _cimg_median_sort(Jab, Jbc);
24348 _cimg_median_sort(Jpp, Jcc); _cimg_median_sort(Jcp, Jac); _cimg_median_sort(Jab, Jpp); _cimg_median_sort(Jab, Jcp);
24349 _cimg_median_sort(Jcc, Jac); _cimg_median_sort(Jbc, Jac); _cimg_median_sort(Jpp, Jcp); _cimg_median_sort(Jbc, Jcc);
24350 _cimg_median_sort(Jpp, Jbc); _cimg_median_sort(Jpp, Jcn); _cimg_median_sort(Jcc, Jcn); _cimg_median_sort(Jcp, Jcn);
24351 _cimg_median_sort(Jcp, Jbc); _cimg_median_sort(Jcc, Jnn); _cimg_median_sort(Jcp, Jcc); _cimg_median_sort(Jbc, Jnn);
24352 _cimg_median_sort(Jcc, Jba); _cimg_median_sort(Jbc, Jba); _cimg_median_sort(Jbc, Jcc);
24357 cimg_forXYC(*
this,x,y,c) {
24359 x0 = x - hl, y0 = y - hl, x1 = x + hr, y1 = y + hr,
24360 nx0 = x0<0?0:x0, ny0 = y0<0?0:y0,
24362 *(ptrd++) =
get_crop(nx0,ny0,0,c,nx1,ny1,0,c).median();
24365 }
else switch (n) {
24368 cimg_forC(*
this,c) cimg_for2x2(*
this,x,y,0,c,I,T) *(ptrd++) = (T)(0.5f*(I[0]+I[1]));
24372 cimg_forC(*
this,c) cimg_for3x3(*
this,x,y,0,c,I,T)
24373 *(ptrd++) = I[3]<I[4]?(I[4]<I[5]?I[4]:(I[3]<I[5]?I[5]:I[3])):(I[3]<I[5]?I[3]:(I[4]<I[5]?I[5]:I[4]));
24376 cimg_forXC(*
this,x,c) {
24378 x0 = x - hl, x1 = x + hr,
24379 nx0 = x0<0?0:x0, nx1 = x1>=
width()?
width()-1:x1;
24380 *(ptrd++) =
get_crop(nx0,0,0,c,nx1,0,0,c).median();
24396 CImg<T>&
sharpen(
const float amplitude,
const bool sharpen_type=
false,
const float edge=1,
const float alpha=0,
const float sigma=0) {
24398 T val_min, val_max =
max_min(val_min);
24399 const float nedge = edge/2;
24400 CImg<Tfloat> val, vec, velocity(_width,_height,_depth,_spectrum);
24401 Tfloat *ptrd = velocity._data, veloc_max = 0;
24404 CImg_3x3x3(I,Tfloat);
24405 if (sharpen_type) {
24407 if (sigma>0) G.blur(sigma);
24408 Tfloat *ptrG0 = G.data(0,0,0,0), *ptrG1 = G.data(0,0,0,1), *ptrG2 = G.data(0,0,0,2), *ptrG3 = G.data(0,0,0,3);
24409 cimg_forXYZ(G,x,y,z) {
24410 G.get_tensor_at(x,y,z).symmetric_eigen(val,vec);
24411 if (val[0]<0) val[0] = 0;
24412 if (val[1]<0) val[1] = 0;
24413 if (val[2]<0) val[2] = 0;
24414 *(ptrG0++) = vec(0,0);
24415 *(ptrG1++) = vec(0,1);
24416 *(ptrG2++) = vec(0,2);
24417 *(ptrG3++) = 1 - (Tfloat)std::pow(1+val[0]+val[1]+val[2],-(Tfloat)nedge);
24419 cimg_forC(*
this,c) cimg_for3x3x3(*
this,x,y,z,c,I,Tfloat) {
24425 ixx = Incc + Ipcc - 2*Iccc,
24426 ixy = (Innc + Ippc - Inpc - Ipnc)/4,
24427 ixz = (Incn + Ipcp - Incp - Ipcn)/4,
24428 iyy = Icnc + Icpc - 2*Iccc,
24429 iyz = (Icnn + Icpp - Icnp - Icpn)/4,
24430 izz = Iccn + Iccp - 2*Iccc,
24437 itt = u*u*ixx + v*v*iyy + w*w*izz + 2*u*v*ixy + 2*u*w*ixz + 2*v*w*iyz,
24441 if (veloc>veloc_max) veloc_max = veloc;
else if (-veloc>veloc_max) veloc_max = -veloc;
24443 }
else cimg_forC(*
this,c) cimg_for3x3x3(*
this,x,y,z,c,I,Tfloat) {
24444 const Tfloat veloc = -Ipcc - Incc - Icpc - Icnc - Iccp - Iccn + 6*Iccc;
24446 if (veloc>veloc_max) veloc_max = veloc;
else if (-veloc>veloc_max) veloc_max = -veloc;
24449 CImg_3x3(I,Tfloat);
24450 if (sharpen_type) {
24452 if (sigma>0) G.blur(sigma);
24453 Tfloat *ptrG0 = G.data(0,0,0,0), *ptrG1 = G.data(0,0,0,1), *ptrG2 = G.data(0,0,0,2);
24454 cimg_forXY(G,x,y) {
24455 G.get_tensor_at(x,y).symmetric_eigen(val,vec);
24456 if (val[0]<0) val[0] = 0;
24457 if (val[1]<0) val[1] = 0;
24458 *(ptrG0++) = vec(0,0);
24459 *(ptrG1++) = vec(0,1);
24460 *(ptrG2++) = 1 - (Tfloat)std::pow(1 + val[0] + val[1],-(Tfloat)nedge);
24462 cimg_forC(*
this,c) cimg_for3x3(*
this,x,y,0,c,I,Tfloat) {
24467 ixx = Inc + Ipc - 2*Icc,
24468 ixy = (Inn + Ipp - Inp - Ipn)/4,
24469 iyy = Icn + Icp - 2*Icc,
24474 itt = u*u*ixx + v*v*iyy + 2*u*v*ixy,
24478 if (veloc>veloc_max) veloc_max = veloc;
else if (-veloc>veloc_max) veloc_max = -veloc;
24480 }
else cimg_forC(*
this,c) cimg_for3x3(*
this,x,y,0,c,I,Tfloat) {
24481 const Tfloat veloc = -Ipc - Inc - Icp - Icn + 4*Icc;
24483 if (veloc>veloc_max) veloc_max = veloc;
else if (-veloc>veloc_max) veloc_max = -veloc;
24486 if (veloc_max<=0)
return *
this;
24487 return ((velocity*=amplitude/veloc_max)+=*
this).
cut(val_min,val_max).move_to(*
this);
24491 CImg<T> get_sharpen(
const float amplitude,
const bool sharpen_type=
false,
const float edge=1,
const float alpha=0,
const float sigma=0)
const {
24492 return (+*
this).
sharpen(amplitude,sharpen_type,edge,alpha,sigma);
24508 Tfloat *ptrd0 = grad[0]._data, *ptrd1 = grad[1]._data;
24509 bool is_3d =
false;
24511 for (
unsigned int a = 0; axes[a]; ++a) {
24514 case 'x' :
case 'y' :
break;
24515 case 'z' : is_3d =
true;
break;
24518 "get_gradient(): Invalid specified axis '%c'.",
24523 }
else is_3d = (_depth>1);
24526 Tfloat *ptrd2 = grad[2]._data;
24529 CImg_3x3x3(I,Tfloat);
24530 cimg_forC(*
this,c) cimg_for3x3x3(*
this,x,y,z,c,I,Tfloat) {
24531 *(ptrd0++) = Iccc - Ipcc;
24532 *(ptrd1++) = Iccc - Icpc;
24533 *(ptrd2++) = Iccc - Iccp;
24537 CImg_2x2x2(I,Tfloat);
24538 cimg_forC(*
this,c) cimg_for2x2x2(*
this,x,y,z,c,I,Tfloat) {
24539 *(ptrd0++) = Incc - Iccc;
24540 *(ptrd1++) = Icnc - Iccc;
24541 *(ptrd2++) = Iccn - Iccc;
24550 CImg_3x3x3(I,Tfloat);
24551 cimg_forC(*
this,c) cimg_for3x3x3(*
this,x,y,z,c,I,Tfloat) {
24552 *(ptrd0++) = (Incc - Ipcc)/2;
24553 *(ptrd1++) = (Icnc - Icpc)/2;
24554 *(ptrd2++) = (Iccn - Iccp)/2;
24558 }
else switch (scheme) {
24560 CImg_3x3(I,Tfloat);
24561 cimg_forZC(*
this,z,c) cimg_for3x3(*
this,x,y,z,c,I,Tfloat) {
24562 *(ptrd0++) = Icc - Ipc;
24563 *(ptrd1++) = Icc - Icp;
24567 CImg_2x2(I,Tfloat);
24568 cimg_forZC(*
this,z,c) cimg_for2x2(*
this,x,y,z,c,I,Tfloat) {
24569 *(ptrd0++) = Inc - Icc;
24570 *(ptrd1++) = Icn - Icc;
24574 CImg_3x3(I,Tfloat);
24575 const Tfloat a = 1, b = 2;
24576 cimg_forZC(*
this,z,c) cimg_for3x3(*
this,x,y,z,c,I,Tfloat) {
24577 *(ptrd0++) = -a*Ipp - b*Ipc - a*Ipn + a*Inp + b*Inc + a*Inn;
24578 *(ptrd1++) = -a*Ipp - b*Icp - a*Inp + a*Ipn + b*Icn + a*Inn;
24582 CImg_3x3(I,Tfloat);
24583 const Tfloat a = (Tfloat)(0.25f*(2-std::sqrt(2.0f))), b = (Tfloat)(0.5f*(std::sqrt(2.0f)-1));
24584 cimg_forZC(*
this,z,c) cimg_for3x3(*
this,x,y,z,c,I,Tfloat) {
24585 *(ptrd0++) = -a*Ipp - b*Ipc - a*Ipn + a*Inp + b*Inc + a*Inn;
24586 *(ptrd1++) = -a*Ipp - b*Icp - a*Inp + a*Ipn + b*Icn + a*Inn;
24594 CImg_3x3(I,Tfloat);
24595 cimg_forZC(*
this,z,c) cimg_for3x3(*
this,x,y,z,c,I,Tfloat) {
24596 *(ptrd0++) = (Inc - Ipc)/2;
24597 *(ptrd1++) = (Icn - Icp)/2;
24601 if (!axes)
return grad;
24603 for (
unsigned int l = 0; axes[l]; ++l) {
24606 case 'x' : res.
insert(grad[0]);
break;
24607 case 'y' : res.
insert(grad[1]);
break;
24608 case 'z' : res.
insert(grad[2]);
break;
24621 const char *naxes = axes, *
const def_axes2d =
"xxxyyy", *
const def_axes3d =
"xxxyxzyyyzzz";
24622 if (!axes) naxes = _depth>1?def_axes3d:def_axes2d;
24623 const unsigned int lmax = std::strlen(naxes);
24626 "get_hessian(): Invalid specified axes '%s'.",
24630 res.
assign(lmax/2,_width,_height,_depth,_spectrum);
24633 *ptrd0 = res[0]._data, *ptrd1 = res[1]._data, *ptrd2 = res[2]._data,
24634 *ptrd3 = res[3]._data, *ptrd4 = res[4]._data, *ptrd5 = res[5]._data;
24635 CImg_3x3x3(I,Tfloat);
24636 cimg_forC(*
this,c) cimg_for3x3x3(*
this,x,y,z,c,I,Tfloat) {
24637 *(ptrd0++) = Ipcc + Incc - 2*Iccc;
24638 *(ptrd1++) = (Ippc + Innc - Ipnc - Inpc)/4;
24639 *(ptrd2++) = (Ipcp + Incn - Ipcn - Incp)/4;
24640 *(ptrd3++) = Icpc + Icnc - 2*Iccc;
24641 *(ptrd4++) = (Icpp + Icnn - Icpn - Icnp)/4;
24642 *(ptrd5++) = Iccn + Iccp - 2*Iccc;
24645 Tfloat *ptrd0 = res[0]._data, *ptrd1 = res[1]._data, *ptrd2 = res[2]._data;
24646 CImg_3x3(I,Tfloat);
24647 cimg_forC(*
this,c) cimg_for3x3(*
this,x,y,0,c,I,Tfloat) {
24648 *(ptrd0++) = Ipc + Inc - 2*Icc;
24649 *(ptrd1++) = (Ipp + Inn - Ipn - Inp)/4;
24650 *(ptrd2++) = Icp + Icn - 2*Icc;
24652 }
else for (
unsigned int l = 0; l<lmax; ) {
24653 const unsigned int l2 = l/2;
24654 char axis1 = naxes[l++], axis2 = naxes[l++];
24656 bool valid_axis =
false;
24657 Tfloat *ptrd = res[l2]._data;
24658 if (axis1==
'x' && axis2==
'x') {
24659 valid_axis =
true; CImg_3x3(I,Tfloat);
24660 cimg_forZC(*
this,z,c) cimg_for3x3(*
this,x,y,z,c,I,Tfloat) *(ptrd++) = Ipc + Inc - 2*Icc;
24662 else if (axis1==
'x' && axis2==
'y') {
24663 valid_axis =
true; CImg_3x3(I,Tfloat);
24664 cimg_forZC(*
this,z,c) cimg_for3x3(*
this,x,y,z,c,I,Tfloat) *(ptrd++) = (Ipp + Inn - Ipn - Inp)/4;
24666 else if (axis1==
'x' && axis2==
'z') {
24667 valid_axis =
true; CImg_3x3x3(I,Tfloat);
24668 cimg_forC(*
this,c) cimg_for3x3x3(*
this,x,y,z,c,I,Tfloat) *(ptrd++) = (Ipcp + Incn - Ipcn - Incp)/4;
24670 else if (axis1==
'y' && axis2==
'y') {
24671 valid_axis =
true; CImg_3x3(I,Tfloat);
24672 cimg_forZC(*
this,z,c) cimg_for3x3(*
this,x,y,z,c,I,Tfloat) *(ptrd++) = Icp + Icn - 2*Icc;
24674 else if (axis1==
'y' && axis2==
'z') {
24675 valid_axis =
true; CImg_3x3x3(I,Tfloat);
24676 cimg_forC(*
this,c) cimg_for3x3x3(*
this,x,y,z,c,I,Tfloat) *(ptrd++) = (Icpp + Icnn - Icpn - Icnp)/4;
24678 else if (axis1==
'z' && axis2==
'z') {
24679 valid_axis =
true; CImg_3x3x3(I,Tfloat);
24680 cimg_forC(*
this,c) cimg_for3x3x3(*
this,x,y,z,c,I,Tfloat) *(ptrd++) = Iccn + Iccp - 2*Iccc;
24682 else if (!valid_axis)
24684 "get_hessian(): Invalid specified axes '%s'.",
24700 Tfloat *ptrd = res._data;
24702 CImg_3x3x3(I,Tfloat);
24703 cimg_forC(*
this,c) cimg_for3x3x3(*
this,x,y,z,c,I,Tfloat)
24704 *(ptrd++) = Incc + Ipcc + Icnc + Icpc + Iccn + Iccp - 6*Iccc;
24705 }
else if (_height>1) {
24706 CImg_3x3(I,Tfloat);
24707 cimg_forC(*
this,c) cimg_for3x3(*
this,x,y,0,c,I,Tfloat)
24708 *(ptrd++) = Inc + Ipc + Icn + Icp - 4*Icc;
24710 CImg_3x3(I,Tfloat);
24711 cimg_forC(*
this,c) cimg_for3x3(*
this,x,y,0,c,I,Tfloat)
24712 *(ptrd++) = Inc + Ipc - 2*Icc;
24730 res.assign(_width,_height,_depth,6,0);
24731 CImg_3x3x3(I,Tfloat);
24734 cimg_forC(*
this,c) {
24736 *ptrd0 = res.data(0,0,0,0), *ptrd1 = res.data(0,0,0,1), *ptrd2 = res.data(0,0,0,2),
24737 *ptrd3 = res.data(0,0,0,3), *ptrd4 = res.data(0,0,0,4), *ptrd5 = res.data(0,0,0,5);
24738 cimg_for3x3x3(*
this,x,y,z,c,I,Tfloat) {
24740 ix = (Incc - Ipcc)/2,
24741 iy = (Icnc - Icpc)/2,
24742 iz = (Iccn - Iccp)/2;
24753 cimg_forC(*
this,c) {
24755 *ptrd0 = res.data(0,0,0,0), *ptrd1 = res.data(0,0,0,1), *ptrd2 = res.data(0,0,0,2),
24756 *ptrd3 = res.data(0,0,0,3), *ptrd4 = res.data(0,0,0,4), *ptrd5 = res.data(0,0,0,5);
24757 cimg_for3x3x3(*
this,x,y,z,c,I,Tfloat) {
24759 ixf = Incc - Iccc, ixb = Iccc - Ipcc,
24760 iyf = Icnc - Iccc, iyb = Iccc - Icpc,
24761 izf = Iccn - Iccc, izb = Iccc - Iccp;
24762 *(ptrd0++)+=(ixf*ixf + ixf*ixb + ixb*ixf + ixb*ixb)/4;
24763 *(ptrd1++)+=(ixf*iyf + ixf*iyb + ixb*iyf + ixb*iyb)/4;
24764 *(ptrd2++)+=(ixf*izf + ixf*izb + ixb*izf + ixb*izb)/4;
24765 *(ptrd3++)+=(iyf*iyf + iyf*iyb + iyb*iyf + iyb*iyb)/4;
24766 *(ptrd4++)+=(iyf*izf + iyf*izb + iyb*izf + iyb*izb)/4;
24767 *(ptrd5++)+=(izf*izf + izf*izb + izb*izf + izb*izb)/4;
24772 cimg_forC(*
this,c) {
24774 *ptrd0 = res.data(0,0,0,0), *ptrd1 = res.data(0,0,0,1), *ptrd2 = res.data(0,0,0,2),
24775 *ptrd3 = res.data(0,0,0,3), *ptrd4 = res.data(0,0,0,4), *ptrd5 = res.data(0,0,0,5);
24776 cimg_for3x3x3(*
this,x,y,z,c,I,Tfloat) {
24778 ixf = Incc - Iccc, ixb = Iccc - Ipcc,
24779 iyf = Icnc - Iccc, iyb = Iccc - Icpc,
24780 izf = Iccn - Iccc, izb = Iccc - Iccp;
24781 *(ptrd0++)+=(ixf*ixf + ixb*ixb)/2;
24782 *(ptrd1++)+=(ixf*iyf + ixf*iyb + ixb*iyf + ixb*iyb)/4;
24783 *(ptrd2++)+=(ixf*izf + ixf*izb + ixb*izf + ixb*izb)/4;
24784 *(ptrd3++)+=(iyf*iyf + iyb*iyb)/2;
24785 *(ptrd4++)+=(iyf*izf + iyf*izb + iyb*izf + iyb*izb)/4;
24786 *(ptrd5++)+=(izf*izf + izb*izb)/2;
24792 res.assign(_width,_height,_depth,3,0);
24793 CImg_3x3(I,Tfloat);
24796 cimg_forC(*
this,c) {
24797 Tfloat *ptrd0 = res.data(0,0,0,0), *ptrd1 = res.data(0,0,0,1), *ptrd2 = res.data(0,0,0,2);
24798 cimg_for3x3(*
this,x,y,0,c,I,Tfloat) {
24800 ix = (Inc - Ipc)/2,
24801 iy = (Icn - Icp)/2;
24809 cimg_forC(*
this,c) {
24810 Tfloat *ptrd0 = res.data(0,0,0,0), *ptrd1 = res.data(0,0,0,1), *ptrd2 = res.data(0,0,0,2);
24811 cimg_for3x3(*
this,x,y,0,c,I,Tfloat) {
24813 ixf = Inc - Icc, ixb = Icc - Ipc,
24814 iyf = Icn - Icc, iyb = Icc - Icp;
24815 *(ptrd0++)+=(ixf*ixf + ixf*ixb + ixb*iyf + ixb*ixb)/4;
24816 *(ptrd1++)+=(ixf*iyf + ixf*iyb + ixb*iyf + ixb*iyb)/4;
24817 *(ptrd2++)+=(iyf*iyf + iyf*iyb + iyb*iyf + iyb*iyb)/4;
24822 cimg_forC(*
this,c) {
24823 Tfloat *ptrd0 = res.data(0,0,0,0), *ptrd1 = res.data(0,0,0,1), *ptrd2 = res.data(0,0,0,2);
24824 cimg_for3x3(*
this,x,y,0,c,I,Tfloat) {
24826 ixf = Inc - Icc, ixb = Icc - Ipc,
24827 iyf = Icn - Icc, iyb = Icc - Icp;
24828 *(ptrd0++)+=(ixf*ixf + ixb*ixb)/2;
24829 *(ptrd1++)+=(ixf*iyf + ixf*iyb + ixb*iyf + ixb*iyb)/4;
24830 *(ptrd2++)+=(iyf*iyf + iyb*iyb)/2;
24848 const float alpha=0.6f,
const float sigma=1.1f,
const bool is_sqrt=
false) {
24850 const float nsharpness =
cimg::max(sharpness,1e-5f), power1 = (is_sqrt?0.5f:1)*nsharpness, power2 = power1/(1e-7f+1-anisotropy);
24851 blur(alpha).normalize(0,(T)255);
24857 *ptrd0 = res.data(0,0,0,0), *ptrd1 = res.data(0,0,0,1), *ptrd2 = res.data(0,0,0,2),
24858 *ptrd3 = res.data(0,0,0,3), *ptrd4 = res.data(0,0,0,4), *ptrd5 = res.data(0,0,0,5);
24859 cimg_forXYZ(*
this,x,y,z) {
24860 res.get_tensor_at(x,y,z).symmetric_eigen(val,vec);
24862 _l1 = val[2], _l2 = val[1], _l3 = val[0],
24863 l1 = _l1>0?_l1:0, l2 = _l2>0?_l2:0, l3 = _l3>0?_l3:0,
24864 ux = vec(0,0), uy = vec(0,1), uz = vec(0,2),
24865 vx = vec(1,0), vy = vec(1,1), vz = vec(1,2),
24866 wx = vec(2,0), wy = vec(2,1), wz = vec(2,2),
24867 n1 = (float)std::pow(1+l1+l2+l3,-power1),
24868 n2 = (float)std::pow(1+l1+l2+l3,-power2);
24869 *(ptrd0++) = n1*(ux*ux + vx*vx) + n2*wx*wx;
24870 *(ptrd1++) = n1*(ux*uy + vx*vy) + n2*wx*wy;
24871 *(ptrd2++) = n1*(ux*uz + vx*vz) + n2*wx*wz;
24872 *(ptrd3++) = n1*(uy*uy + vy*vy) + n2*wy*wy;
24873 *(ptrd4++) = n1*(uy*uz + vy*vz) + n2*wy*wz;
24874 *(ptrd5++) = n1*(uz*uz + vz*vz) + n2*wz*wz;
24879 Tfloat *ptrd0 = res.data(0,0,0,0), *ptrd1 = res.data(0,0,0,1), *ptrd2 = res.data(0,0,0,2);
24880 cimg_forXY(*
this,x,y) {
24881 res.get_tensor_at(x,y).symmetric_eigen(val,vec);
24883 _l1 = val[1], _l2 = val[0],
24884 l1 = _l1>0?_l1:0, l2 = _l2>0?_l2:0,
24885 ux = vec(1,0), uy = vec(1,1),
24886 vx = vec(0,0), vy = vec(0,1),
24887 n1 = (float)std::pow(1+l1+l2,-power1),
24888 n2 = (float)std::pow(1+l1+l2,-power2);
24889 *(ptrd0++) = n1*ux*ux + n2*vx*vx;
24890 *(ptrd1++) = n1*ux*uy + n2*vx*vy;
24891 *(ptrd2++) = n1*uy*uy + n2*vy*vy;
24894 return res.move_to(*
this);
24899 const float alpha=0.6f,
const float sigma=1.1f,
const bool is_sqrt=
false)
const {
24913 const unsigned int nb_scales=0,
const unsigned int iteration_max=10000,
24914 const bool is_backward=
false) {
24915 return get_displacement(source,smoothness,precision,nb_scales,iteration_max,is_backward).move_to(*
this);
24920 const float smoothness=0.1f,
const float precision=5.0f,
24921 const unsigned int nb_scales=0,
const unsigned int iteration_max=10000,
24922 const bool is_backward=
false)
const {
24923 if (
is_empty() || !source)
return +*
this;
24926 "displacement(): Instance and source image (%u,%u,%u,%u,%p) have different dimensions.",
24928 source._width,source._height,source._depth,source._spectrum,source._data);
24931 "displacement(): Invalid specified precision %g "
24935 const unsigned int _nb_scales = nb_scales>0?nb_scales:(
unsigned int)(2*std::log((
double)(
cimg::max(_width,_height))));
24936 const float _precision = (float)std::pow(10.0,-(
double)precision);
24937 float sm, sM = source.max_min(sm), tm, tM =
max_min(tm);
24938 const float sdelta = sm==sM?1:(sM - sm), tdelta = tm==tM?1:(tM - tm);
24939 const bool is_3d = source._depth>1;
24942 for (
int scale = _nb_scales-1; scale>=0; --scale) {
24943 const float factor = (float)std::pow(1.5,(
double)scale);
24945 _sw = (
unsigned int)(_width/factor), sw = _sw?_sw:1,
24946 _sh = (
unsigned int)(_height/factor), sh = _sh?_sh:1,
24947 _sd = (
unsigned int)(_depth/factor), sd = _sd?_sd:1;
24948 if (sw<5 && sh<5 && (!is_3d || sd<5))
continue;
24950 I1 = (source.get_resize(sw,sh,sd,-100,2)-=sm)/=sdelta,
24952 if (U) (U*=1.5f).
resize(I2._width,I2._height,I2._depth,-100,3);
24953 else U.
assign(I2._width,I2._height,I2._depth,is_3d?3:2,0);
24955 const CImgList<Tfloat> dI = is_backward?I1.get_gradient():I2.get_gradient();
24957 for (
unsigned int iteration = 0; iteration<iteration_max; ++iteration) {
24960 if (smoothness>=0) cimg_for3XYZ(U,x,y,z) {
24962 X = is_backward?x - U(x,y,z,0):x + U(x,y,z,0),
24963 Y = is_backward?y - U(x,y,z,1):y + U(x,y,z,1),
24964 Z = is_backward?z - U(x,y,z,2):z + U(x,y,z,2);
24965 float delta_I = 0, _energy_regul = 0;
24966 if (is_backward) cimg_forC(I2,c) delta_I+=(float)(I1.linear_atXYZ(X,Y,Z,c) - I2(x,y,z,c));
24967 else cimg_forC(I2,c) delta_I+=(float)(I1(x,y,z,c) - I2.linear_atXYZ(X,Y,Z,c));
24970 Ux = 0.5f*(U(_n1x,y,z,c) - U(_p1x,y,z,c)),
24971 Uy = 0.5f*(U(x,_n1y,z,c) - U(x,_p1y,z,c)),
24972 Uz = 0.5f*(U(x,y,_n1z,c) - U(x,y,_p1z,c)),
24973 Uxx = U(_n1x,y,z,c) + U(_p1x,y,z,c),
24974 Uyy = U(x,_n1y,z,c) + U(x,_p1y,z,c),
24975 Uzz = U(x,y,_n1z,c) + U(x,y,_p1z,c);
24976 U(x,y,z,c) = (float)(U(x,y,z,c) + dt*(delta_I*dI[c].linear_atXYZ(X,Y,Z) + smoothness* ( Uxx + Uyy + Uzz)))/(1+6*smoothness*dt);
24977 _energy_regul+=Ux*Ux + Uy*Uy + Uz*Uz;
24979 _energy+=delta_I*delta_I + smoothness*_energy_regul;
24981 const float nsmoothness = -smoothness;
24982 cimg_for3XYZ(U,x,y,z) {
24984 X = is_backward?x - U(x,y,z,0):x + U(x,y,z,0),
24985 Y = is_backward?y - U(x,y,z,1):y + U(x,y,z,1),
24986 Z = is_backward?z - U(x,y,z,2):z + U(x,y,z,2);
24987 float delta_I = 0, _energy_regul = 0;
24988 if (is_backward) cimg_forC(I2,c) delta_I+=(float)(I1.linear_atXYZ(X,Y,Z,c) - I2(x,y,z,c));
24989 else cimg_forC(I2,c) delta_I+=(float)(I1(x,y,z,c) - I2.linear_atXYZ(X,Y,Z,c));
24992 Ux = 0.5f*(U(_n1x,y,z,c) - U(_p1x,y,z,c)),
24993 Uy = 0.5f*(U(x,_n1y,z,c) - U(x,_p1y,z,c)),
24994 Uz = 0.5f*(U(x,y,_n1z,c) - U(x,y,_p1z,c)),
24995 N2 = Ux*Ux + Uy*Uy + Uz*Uz,
24998 coef_a = (1 - Ux*Ux/N2)/N,
24999 coef_b = -2*Ux*Uy/N3,
25000 coef_c = -2*Ux*Uz/N3,
25001 coef_d = (1 - Uy*Uy/N2)/N,
25002 coef_e = -2*Uy*Uz/N3,
25003 coef_f = (1 - Uz*Uz/N2)/N,
25004 Uxx = U(_n1x,y,z,c) + U(_p1x,y,z,c),
25005 Uyy = U(x,_n1y,z,c) + U(x,_p1y,z,c),
25006 Uzz = U(x,y,_n1z,c) + U(x,y,_p1z,c),
25007 Uxy = 0.25f*(U(_n1x,_n1y,z,c) + U(_p1x,_p1y,z,c) - U(_n1x,_p1y,z,c) - U(_n1x,_p1y,z,c)),
25008 Uxz = 0.25f*(U(_n1x,y,_n1z,c) + U(_p1x,y,_p1z,c) - U(_n1x,y,_p1z,c) - U(_n1x,y,_p1z,c)),
25009 Uyz = 0.25f*(U(x,_n1y,_n1z,c) + U(x,_p1y,_p1z,c) - U(x,_n1y,_p1z,c) - U(x,_n1y,_p1z,c));
25010 U(x,y,z,c) = (float)(U(x,y,z,c) + dt*(delta_I*dI[c].linear_atXYZ(X,Y,Z) +
25011 nsmoothness* ( coef_a*Uxx + coef_b*Uxy + coef_c*Uxz + coef_d*Uyy + coef_e*Uyz + coef_f*Uzz ))
25012 )/(1+2*(coef_a+coef_d+coef_f)*nsmoothness*dt);
25015 _energy+=delta_I*delta_I + nsmoothness*_energy_regul;
25019 if (smoothness>=0) cimg_for3XY(U,x,y) {
25021 X = is_backward?x - U(x,y,0):x + U(x,y,0),
25022 Y = is_backward?y - U(x,y,1):y + U(x,y,1);
25023 float delta_I = 0, _energy_regul = 0;
25024 if (is_backward) cimg_forC(I2,c) delta_I+=(float)(I1.linear_atXY(X,Y,c) - I2(x,y,c));
25025 else cimg_forC(I2,c) delta_I+=(float)(I1(x,y,c) - I2.linear_atXY(X,Y,c));
25028 Ux = 0.5f*(U(_n1x,y,c) - U(_p1x,y,c)),
25029 Uy = 0.5f*(U(x,_n1y,c) - U(x,_p1y,c)),
25030 Uxx = U(_n1x,y,c) + U(_p1x,y,c),
25031 Uyy = U(x,_n1y,c) + U(x,_p1y,c);
25032 U(x,y,c) = (float)(U(x,y,c) + dt*(delta_I*dI[c].linear_atXY(X,Y) + smoothness*( Uxx + Uyy )))/(1+4*smoothness*dt);
25033 _energy_regul+=Ux*Ux + Uy*Uy;
25035 _energy+=delta_I*delta_I + smoothness*_energy_regul;
25037 const float nsmoothness = -smoothness;
25038 cimg_for3XY(U,x,y) {
25040 X = is_backward?x - U(x,y,0):x + U(x,y,0),
25041 Y = is_backward?y - U(x,y,1):y + U(x,y,1);
25042 float delta_I = 0, _energy_regul = 0;
25043 if (is_backward) cimg_forC(I2,c) delta_I+=(float)(I1.linear_atXY(X,Y,c) - I2(x,y,c));
25044 else cimg_forC(I2,c) delta_I+=(float)(I1(x,y,c) - I2.linear_atXY(X,Y,c));
25047 Ux = 0.5f*(U(_n1x,y,c) - U(_p1x,y,c)),
25048 Uy = 0.5f*(U(x,_n1y,c) - U(x,_p1y,c)),
25049 N2 = Ux*Ux + Uy*Uy,
25053 coef_b = -2*Ux*Uy/N3,
25055 Uxx = U(_n1x,y,c) + U(_p1x,y,c),
25056 Uyy = U(x,_n1y,c) + U(x,_p1y,c),
25057 Uxy = 0.25f*(U(_n1x,_n1y,c) + U(_p1x,_p1y,c) - U(_n1x,_p1y,c) - U(_n1x,_p1y,c));
25058 U(x,y,c) = (float)(U(x,y,c) + dt*(delta_I*dI[c].linear_atXY(X,Y) + nsmoothness*( coef_a*Uxx + coef_b*Uxy + coef_c*Uyy )))/(1+2*(coef_a+coef_c)*nsmoothness*dt);
25061 _energy+=delta_I*delta_I + nsmoothness*_energy_regul;
25065 const float d_energy = (_energy - energy)/(sw*sh*sd);
25066 if (d_energy<=0 && -d_energy<_precision)
break;
25067 if (d_energy>0) dt*=0.5f;
25088 bool is_value =
false;
25089 cimg_for(*
this,ptr,T) *ptr = (T)(*ptr==value?is_value=
true,0:999999999);
25092 case 0 :
return _distance_core(_distance_sep_cdt,_distance_dist_cdt);
25093 case 1 :
return _distance_core(_distance_sep_mdt,_distance_dist_mdt);
25094 case 3 :
return _distance_core(_distance_sep_edt,_distance_dist_edt);
25095 default :
return _distance_core(_distance_sep_edt,_distance_dist_edt).sqrt();
25105 static long _distance_sep_edt(
const long i,
const long u,
const long *
const g) {
25106 return (u*u-i*i+g[u]-g[i])/(2*(u-i));
25109 static long _distance_dist_edt(
const long x,
const long i,
const long *
const g) {
25110 return (x-i)*(x-i) + g[i];
25113 static long _distance_sep_mdt(
const long i,
const long u,
const long *
const g) {
25114 return (u-i<=g[u]-g[i]?999999999:(g[u]-g[i]+u+i)/2);
25117 static long _distance_dist_mdt(
const long x,
const long i,
const long *
const g) {
25118 return (x<i?i-x:x-i) + g[i];
25121 static long _distance_sep_cdt(
const long i,
const long u,
const long *
const g) {
25122 const long h = (i+u)/2;
25123 if (g[i]<=g[u]) {
return h<i+g[u]?i+g[u]:h; }
25124 return h<u-g[i]?h:u-g[i];
25127 static long _distance_dist_cdt(
const long x,
const long i,
const long *
const g) {
25128 const long d = x<i?i-x:x-i;
25129 return d<g[i]?g[i]:d;
25132 static void _distance_scan(
const unsigned int len,
25133 const long *
const g,
25134 long (*
const sep)(
const long,
const long,
const long *
const),
25135 long (*
const f)(
const long,
const long,
const long *
const),
25139 long q = s[0] = t[0] = 0;
25140 for (
int u = 1; u<(int)len; ++u) {
25141 while ((q>=0) && f(t[q],s[q],g)>f(t[q],u,g)) { --q; }
25142 if (q<0) { q = 0; s[0] = u; }
25143 else {
const long w = 1 + sep(s[q], u, g);
if (w<(
long)len) { ++q; s[q] = u; t[q] = w; }}
25145 for (
int u = (
int)len-1; u>=0; --u) { dt[u] = f(u,s[q],g);
if (u==t[q]) --q; }
25148 CImg<T>& _distance_core(
long (*
const sep)(
const long,
const long,
const long *
const),
25149 long (*
const f)(
const long,
const long,
const long *
const)) {
25150 const unsigned long wh = (
unsigned long)_width*_height;
25151 cimg_forC(*
this,c) {
25152 CImg<longT> g(_width), dt(_width), s(_width), t(_width);
25154 cimg_forYZ(*
this,y,z) {
25155 cimg_forX(*
this,x) g[x] = (
long)img(x,y,z,0,wh);
25156 _distance_scan(_width,g,sep,f,s,t,dt);
25157 cimg_forX(*this,x) img(x,y,z,0,wh) = (T)dt[x];
25160 cimg_forXZ(*this,x,z) {
25161 cimg_forY(*
this,y) g[y] = (
long)img(x,y,z,0,wh);
25162 _distance_scan(_height,g,sep,f,s,t,dt);
25163 cimg_forY(*this,y) img(x,y,z,0,wh) = (T)dt[y];
25166 g.assign(_depth); dt.assign(_depth); s.assign(_depth); t.assign(_depth);
25167 cimg_forXY(*
this,x,y) {
25168 cimg_forZ(*
this,z) g[z] = (
long)img(x,y,z,0,wh);
25169 _distance_scan(_depth,g,sep,f,s,t,dt);
25170 cimg_forZ(*this,z) img(x,y,z,0,wh) = (T)dt[z];
25183 template<typename t>
25186 bool is_value =
false;
25187 cimg_for(*
this,ptr,T) *ptr = (T)(*ptr==value?is_value=
true,0:999999999);
25189 const unsigned long wh = (
unsigned long)_width*_height;
25190 cimg_forC(*
this,c) {
25192 cimg_forXYZ(metric_mask,dx,dy,dz) {
25193 const t weight = metric_mask(dx,dy,dz);
25195 for (
int z = dz, nz = 0; z<
depth(); ++z,++nz) {
25196 for (
int y = dy , ny = 0; y<
height(); ++y,++ny) {
25197 for (
int x = dx, nx = 0; x<
width(); ++x,++nx) {
25198 const T dd = img(nx,ny,nz,0,wh) + weight;
25199 if (dd<img(x,y,z,0,wh)) img(x,y,z,0,wh) = dd;
25203 for (
int z =
depth() - 1 - dz, nz =
depth() - 1; z>=0; --z,--nz) {
25204 for (
int y =
height() - 1 - dy, ny =
height() - 1; y>=0; --y,--ny) {
25205 for (
int x =
width() - 1 - dx, nx =
width() - 1; x>=0; --x,--nx) {
25206 const T dd = img(nx,ny,nz,0,wh) + weight;
25207 if (dd<img(x,y,z,0,wh)) img(x,y,z,0,wh) = dd;
25218 template<
typename t>
25239 "distance_dijkstra(): image instance does not contain specified starting point (%u,%u,%u).",
25244 "distance_dijkstra(): image instance is not a scalar image.",
25249 unsigned int sizeQ = 0;
25252 Q._priority_queue_insert(in_queue,sizeQ,0,x,y,z);
25253 res(x,y,z) = 0; res(x,y,z,1) = 0;
25259 const int x = (int)Q(0,1), y = (int)Q(0,2), z = (int)Q(0,3);
25260 const Tfloat potential = (Tfloat)-Q(0,0);
25261 Q._priority_queue_remove(sizeQ);
25265 if (x-1>=0 && Q._priority_queue_insert(in_queue,sizeQ,-(npot=(*
this)(x-1,y,z)+potential),x-1,y,z)) {
25266 res(x-1,y,z) = npot; res(x-1,y,z,1) = 2;
25268 if (x+1<
width() && Q._priority_queue_insert(in_queue,sizeQ,-(npot=(*
this)(x+1,y,z)+potential),x+1,y,z)) {
25269 res(x+1,y,z) = npot; res(x+1,y,z,1) = 1;
25271 if (y-1>=0 && Q._priority_queue_insert(in_queue,sizeQ,-(npot=(*
this)(x,y-1,z)+potential),x,y-1,z)) {
25272 res(x,y-1,z) = npot; res(x,y-1,z,1) = 4;
25274 if (y+1<
height() && Q._priority_queue_insert(in_queue,sizeQ,-(npot=(*
this)(x,y+1,z)+potential),x,y+1,z)) {
25275 res(x,y+1,z) = npot; res(x,y+1,z,1) = 3;
25277 if (z-1>=0 && Q._priority_queue_insert(in_queue,sizeQ,-(npot=(*
this)(x,y,z-1)+potential),x,y,z-1)) {
25278 res(x,y,z-1) = npot; res(x,y,z-1,1) = 6;
25280 if (z+1<
depth() && Q._priority_queue_insert(in_queue,sizeQ,-(npot=(*
this)(x,y,z+1)+potential),x,y,z+1)) {
25281 res(x,y,z+1) = npot; res(x,y,z+1,1) = 5;
25296 for (
unsigned int iteration = 0; iteration<nb_iterations; ++iteration) {
25297 Tfloat *ptrd = velocity._data, veloc_max = 0;
25299 CImg_3x3x3(I,Tfloat);
25300 cimg_forC(*
this,c) cimg_for3x3x3(*
this,x,y,z,c,I,Tfloat)
if (band_size<=0 ||
cimg::abs(Iccc)<band_size) {
25302 gx = (Incc - Ipcc)/2,
25303 gy = (Icnc - Icpc)/2,
25304 gz = (Iccn - Iccp)/2,
25306 ix = gx*sgn>0?(Incc - Iccc):(Iccc - Ipcc),
25307 iy = gy*sgn>0?(Icnc - Iccc):(Iccc - Icpc),
25308 iz = gz*sgn>0?(Iccn - Iccc):(Iccc - Iccp),
25309 ng = (Tfloat)(1e-5f + std::sqrt(gx*gx + gy*gy + gz*gz)),
25313 veloc = sgn*(ngx*ix + ngy*iy + ngz*iz - 1);
25315 if (veloc>veloc_max) veloc_max = veloc;
else if (-veloc>veloc_max) veloc_max = -veloc;
25316 }
else *(ptrd++) = 0;
25318 CImg_3x3(I,Tfloat);
25319 cimg_forC(*
this,c) cimg_for3x3(*
this,x,y,0,c,I,Tfloat)
if (band_size<=0 ||
cimg::abs(Icc)<band_size) {
25321 gx = (Inc - Ipc)/2,
25322 gy = (Icn - Icp)/2,
25324 ix = gx*sgn>0?(Inc - Icc):(Icc - Ipc),
25325 iy = gy*sgn>0?(Icn - Icc):(Icc - Icp),
25326 ng = (Tfloat)(1e-5f + std::sqrt(gx*gx + gy*gy)),
25329 veloc = sgn*(ngx*ix + ngy*iy - 1);
25331 if (veloc>veloc_max) veloc_max = veloc;
else if (-veloc>veloc_max) veloc_max = -veloc;
25332 }
else *(ptrd++) = 0;
25334 if (veloc_max>0) *
this+=(velocity*=time_step/veloc_max);
25356 if (
is_empty() || !nb_scales)
return +*
this;
25358 const Tfloat sqrt2 = std::sqrt(2);
25359 if (nb_scales==1) {
25362 const unsigned int w = _width/2;
25366 "haar(): Sub-image width %u is not even at scale %u.",
25370 res.assign(_width,_height,_depth,_spectrum);
25371 if (
invert) cimg_forYZC(*
this,y,z,c) {
25372 for (
unsigned int x = 0, xw = w, x2 = 0; x<w; ++x, ++xw) {
25373 const Tfloat val0 = (Tfloat)(*
this)(x,y,z,c), val1 = (Tfloat)(*this)(xw,y,z,c);
25374 res(x2++,y,z,c) = val0 - val1;
25375 res(x2++,y,z,c) = val0 + val1;
25377 }
else cimg_forYZC(*
this,y,z,c) {
25378 for (
unsigned int x = 0, xw = w, x2 = 0; x<w; ++x, ++xw) {
25379 const Tfloat val0 = (Tfloat)(*
this)(x2++,y,z,c), val1 = (Tfloat)(*this)(x2++,y,z,c);
25380 res(x,y,z,c) = (val0 + val1)/2;
25381 res(xw,y,z,c) = (val1 - val0)/2;
25384 }
else return *
this;
25387 const unsigned int h = _height/2;
25391 "haar(): Sub-image height %u is not even at scale %u.",
25395 res.assign(_width,_height,_depth,_spectrum);
25396 if (
invert) cimg_forXZC(*
this,x,z,c) {
25397 for (
unsigned int y = 0, yh = h, y2 = 0; y<h; ++y, ++yh) {
25398 const Tfloat val0 = (Tfloat)(*
this)(x,y,z,c), val1 = (Tfloat)(*this)(x,yh,z,c);
25399 res(x,y2++,z,c) = (val0 - val1)/sqrt2;
25400 res(x,y2++,z,c) = (val0 + val1)/sqrt2;
25402 }
else cimg_forXZC(*
this,x,z,c) {
25403 for (
unsigned int y = 0, yh = h, y2 = 0; y<h; ++y, ++yh) {
25404 const Tfloat val0 = (Tfloat)(*
this)(x,y2++,z,c), val1 = (Tfloat)(*this)(x,y2++,z,c);
25405 res(x,y,z,c) = (val0 + val1)/sqrt2;
25406 res(x,yh,z,c) = (val1 - val0)/sqrt2;
25409 }
else return *
this;
25412 const unsigned int d = _depth/2;
25416 "haar(): Sub-image depth %u is not even at scale %u.",
25420 res.assign(_width,_height,_depth,_spectrum);
25421 if (
invert) cimg_forXYC(*
this,x,y,c) {
25422 for (
unsigned int z = 0, zd = d, z2 = 0; z<d; ++z, ++zd) {
25423 const Tfloat val0 = (Tfloat)(*
this)(x,y,z,c), val1 = (Tfloat)(*this)(x,y,zd,c);
25424 res(x,y,z2++,c) = (val0 - val1)/sqrt2;
25425 res(x,y,z2++,c) = (val0 + val1)/sqrt2;
25427 }
else cimg_forXYC(*
this,x,y,c) {
25428 for (
unsigned int z = 0, zd = d, z2 = 0; z<d; ++z, ++zd) {
25429 const Tfloat val0 = (Tfloat)(*
this)(x,y,z2++,c), val1 = (Tfloat)(*this)(x,y,z2++,c);
25430 res(x,y,z,c) = (val0 + val1)/sqrt2;
25431 res(x,y,zd,c) = (val1 - val0)/sqrt2;
25434 }
else return *
this;
25438 "haar(): Invalid specified axis '%c' "
25439 "(should be { x | y | z }).",
25448 unsigned int w = _width;
25449 for (
unsigned int s = 1; w && s<nb_scales; ++s) w/=2;
25450 for (w = w?w:1; w<=_width; w*=2) res.draw_image(res.get_crop(0,w-1).get_haar(
'x',
true,1));
25453 unsigned int h = _width;
25454 for (
unsigned int s = 1; h && s<nb_scales; ++s) h/=2;
25455 for (h = h?h:1; h<=_height; h*=2) res.draw_image(res.get_crop(0,0,_width-1,h-1).get_haar(
'y',
true,1));
25458 unsigned int d = _depth;
25459 for (
unsigned int s = 1; d && s<nb_scales; ++s) d/=2;
25460 for (d = d?d:1; d<=_depth; d*=2) res.draw_image(res.get_crop(0,0,0,_width-1,_height-1,d-1).get_haar(
'z',
true,1));
25464 "haar(): Invalid specified axis '%c' "
25465 "(should be { x | y | z }).",
25473 for (
unsigned int s = 1, w = _width/2; w && s<nb_scales; ++s, w/=2) res.draw_image(res.get_crop(0,w-1).get_haar(
'x',
false,1));
25476 for (
unsigned int s = 1, h = _height/2; h && s<nb_scales; ++s, h/=2) res.draw_image(res.get_crop(0,0,_width-1,h-1).get_haar(
'y',
false,1));
25479 for (
unsigned int s = 1, d = _depth/2; d && s<nb_scales; ++s, d/=2) res.draw_image(res.get_crop(0,0,0,_width-1,_height-1,d-1).get_haar(
'z',
false,1));
25483 "haar(): Invalid specified axis '%c' "
25484 "(should be { x | y | z }).",
25506 if (nb_scales==1) {
25510 if (res)
return res;
25517 unsigned int w = _width, h = _height, d = _depth;
for (
unsigned int s = 1; w && h && d && s<nb_scales; ++s) { w/=2; h/=2; d/=2; }
25518 for (w = w?w:1, h = h?h:1, d = d?d:1; w<=_width && h<=_height && d<=_depth; w*=2, h*=2, d*=2)
25519 res.draw_image(res.get_crop(0,0,0,w-1,h-1,d-1).get_haar(
true,1));
25521 unsigned int w = _width, h = _height;
for (
unsigned int s = 1; w && h && s<nb_scales; ++s) { w/=2; h/=2; }
25522 for (w = w?w:1, h = h?h:1; w<=_width && h<=_height; w*=2, h*=2)
25523 res.draw_image(res.get_crop(0,0,0,w-1,h-1,0).get_haar(
true,1));
25527 unsigned int w = _width, d = _depth;
for (
unsigned int s = 1; w && d && s<nb_scales; ++s) { w/=2; d/=2; }
25528 for (w = w?w:1, d = d?d:1; w<=_width && d<=_depth; w*=2, d*=2)
25529 res.draw_image(res.get_crop(0,0,0,w-1,0,d-1).get_haar(
true,1));
25531 unsigned int w = _width;
for (
unsigned int s = 1; w && s<nb_scales; ++s) w/=2;
25532 for (w = w?w:1; w<=_width; w*=2)
25533 res.draw_image(res.get_crop(0,0,0,w-1,0,0).get_haar(
true,1));
25539 unsigned int h = _height, d = _depth;
for (
unsigned int s = 1; h && d && s<nb_scales; ++s) { h/=2; d/=2; }
25540 for (h = h?h:1, d = d?d:1; h<=_height && d<=_depth; h*=2, d*=2)
25541 res.draw_image(res.get_crop(0,0,0,0,h-1,d-1).get_haar(
true,1));
25543 unsigned int h = _height;
for (
unsigned int s = 1; h && s<nb_scales; ++s) h/=2;
25544 for (h = h?h:1; h<=_height; h*=2)
25545 res.draw_image(res.get_crop(0,0,0,0,h-1,0).get_haar(
true,1));
25549 unsigned int d = _depth;
for (
unsigned int s = 1; d && s<nb_scales; ++s) d/=2;
25550 for (d = d?d:1; d<=_depth; d*=2)
25551 res.draw_image(res.get_crop(0,0,0,0,0,d-1).get_haar(
true,1));
25552 }
else return *
this;
25559 if (_depth>1)
for (
unsigned int s = 1, w = _width/2, h = _height/2, d = _depth/2; w && h && d && s<nb_scales; ++s, w/=2, h/=2, d/=2)
25560 res.draw_image(res.get_crop(0,0,0,w-1,h-1,d-1).haar(
false,1));
25561 else for (
unsigned int s = 1, w = _width/2, h = _height/2; w && h && s<nb_scales; ++s, w/=2, h/=2)
25562 res.draw_image(res.get_crop(0,0,0,w-1,h-1,0).haar(
false,1));
25564 if (_depth>1)
for (
unsigned int s = 1, w = _width/2, d = _depth/2; w && d && s<nb_scales; ++s, w/=2, d/=2)
25565 res.draw_image(res.get_crop(0,0,0,w-1,0,d-1).haar(
false,1));
25566 else for (
unsigned int s = 1, w = _width/2; w && s<nb_scales; ++s, w/=2)
25567 res.draw_image(res.get_crop(0,0,0,w-1,0,0).haar(
false,1));
25571 if (_depth>1)
for (
unsigned int s = 1, h = _height/2, d = _depth/2; h && d && s<nb_scales; ++s, h/=2, d/=2)
25572 res.draw_image(res.get_crop(0,0,0,0,h-1,d-1).haar(
false,1));
25573 else for (
unsigned int s = 1, h = _height/2; h && s<nb_scales; ++s, h/=2)
25574 res.draw_image(res.get_crop(0,0,0,0,h-1,0).haar(
false,1));
25576 if (_depth>1)
for (
unsigned int s = 1, d = _depth/2; d && s<nb_scales; ++s, d/=2)
25577 res.draw_image(res.get_crop(0,0,0,0,0,d-1).haar(
false,1));
25620 if (!imag) imag.assign(real._width,real._height,real._depth,real._spectrum,0);
25621 if (!real.is_sameXYZC(imag))
25622 throw CImgInstanceException(
"CImg<%s>::FFT(): Specified real part (%u,%u,%u,%u,%p) and imaginary part (%u,%u,%u,%u,%p) have different dimensions.",
25624 real._width,real._height,real._depth,real._spectrum,real._data,
25625 imag._width,imag._height,imag._depth,imag._spectrum,imag._data);
25626 #ifdef cimg_use_fftw3
25627 fftw_complex *data_in;
25628 fftw_plan data_plan;
25632 data_in = (fftw_complex*)fftw_malloc(
sizeof(fftw_complex)*real._width);
25633 if (!data_in)
throw CImgInstanceException(
"CImgList<%s>::FFT(): Failed to allocate memory (%s) for computing FFT of image (%u,%u,%u,%u) along the X-axis.",
25635 cimg::strbuffersize(
sizeof(fftw_complex)*real._width),
25636 real._width,real._height,real._depth,real._spectrum);
25638 data_plan = fftw_plan_dft_1d(real._width,data_in,data_in,is_invert?FFTW_BACKWARD:FFTW_FORWARD,FFTW_ESTIMATE);
25639 cimg_forYZC(real,y,z,c) {
25640 T *ptrr = real.data(0,y,z,c), *ptri = imag.data(0,y,z,c);
25641 double *ptrd = (
double*)data_in;
25642 cimg_forX(real,x) { *(ptrd++) = (
double)*(ptrr++); *(ptrd++) = (
double)*(ptri++); }
25643 fftw_execute(data_plan);
25644 const unsigned int fact = real._width;
25645 if (is_invert) cimg_forX(real,x) { *(--ptri) = (T)(*(--ptrd)/fact); *(--ptrr) = (T)(*(--ptrd)/fact); }
25646 else cimg_forX(real,x) { *(--ptri) = (T)*(--ptrd); *(--ptrr) = (T)*(--ptrd); }
25650 data_in = (fftw_complex*)fftw_malloc(
sizeof(fftw_complex) * real._height);
25651 if (!data_in)
throw CImgInstanceException(
"CImgList<%s>::FFT(): Failed to allocate memory (%s) for computing FFT of image (%u,%u,%u,%u) along the Y-axis.",
25653 cimg::strbuffersize(
sizeof(fftw_complex)*real._height),
25654 real._width,real._height,real._depth,real._spectrum);
25656 data_plan = fftw_plan_dft_1d(real._height,data_in,data_in,is_invert?FFTW_BACKWARD:FFTW_FORWARD,FFTW_ESTIMATE);
25657 const unsigned int off = real._width;
25658 cimg_forXZC(real,x,z,c) {
25659 T *ptrr = real.data(x,0,z,c), *ptri = imag.data(x,0,z,c);
25660 double *ptrd = (
double*)data_in;
25661 cimg_forY(real,y) { *(ptrd++) = (
double)*ptrr; *(ptrd++) = (
double)*ptri; ptrr+=off; ptri+=off; }
25662 fftw_execute(data_plan);
25663 const unsigned int fact = real._height;
25664 if (is_invert) cimg_forY(real,y) { ptrr-=off; ptri-=off; *ptri = (T)(*(--ptrd)/fact); *ptrr = (T)(*(--ptrd)/fact); }
25665 else cimg_forY(real,y) { ptrr-=off; ptri-=off; *ptri = (T)*(--ptrd); *ptrr = (T)*(--ptrd); }
25669 data_in = (fftw_complex*)fftw_malloc(
sizeof(fftw_complex) * real._depth);
25670 if (!data_in)
throw CImgInstanceException(
"CImgList<%s>::FFT(): Failed to allocate memory (%s) for computing FFT of image (%u,%u,%u,%u) along the Z-axis.",
25672 cimg::strbuffersize(
sizeof(fftw_complex)*real._depth),
25673 real._width,real._height,real._depth,real._spectrum);
25675 data_plan = fftw_plan_dft_1d(real._depth,data_in,data_in,is_invert?FFTW_BACKWARD:FFTW_FORWARD,FFTW_ESTIMATE);
25676 const unsigned long off = (
unsigned long)real._width*real._height;
25677 cimg_forXYC(real,x,y,c) {
25678 T *ptrr = real.data(x,y,0,c), *ptri = imag.data(x,y,0,c);
25679 double *ptrd = (
double*)data_in;
25680 cimg_forZ(real,z) { *(ptrd++) = (
double)*ptrr; *(ptrd++) = (
double)*ptri; ptrr+=off; ptri+=off; }
25681 fftw_execute(data_plan);
25682 const unsigned int fact = real._depth;
25683 if (is_invert) cimg_forZ(real,z) { ptrr-=off; ptri-=off; *ptri = (T)(*(--ptrd)/fact); *ptrr = (T)(*(--ptrd)/fact); }
25684 else cimg_forZ(real,z) { ptrr-=off; ptri-=off; *ptri = (T)*(--ptrd); *ptrr = (T)*(--ptrd); }
25688 data_in = (fftw_complex*)fftw_malloc(
sizeof(fftw_complex) * real._spectrum);
25689 if (!data_in)
throw CImgInstanceException(
"CImgList<%s>::FFT(): Failed to allocate memory (%s) for computing FFT of image (%u,%u,%u,%u) along the C-axis.",
25691 cimg::strbuffersize(
sizeof(fftw_complex)*real._spectrum),
25692 real._width,real._height,real._depth,real._spectrum);
25694 data_plan = fftw_plan_dft_1d(real._spectrum,data_in,data_in,is_invert?FFTW_BACKWARD:FFTW_FORWARD,FFTW_ESTIMATE);
25695 const unsigned long off = (
unsigned long)real._width*real._height*real._depth;
25696 cimg_forXYZ(real,x,y,z) {
25697 T *ptrr = real.data(x,y,z,0), *ptri = imag.data(x,y,z,0);
25698 double *ptrd = (
double*)data_in;
25699 cimg_forC(real,c) { *(ptrd++) = (
double)*ptrr; *(ptrd++) = (
double)*ptri; ptrr+=off; ptri+=off; }
25700 fftw_execute(data_plan);
25701 const unsigned int fact = real._spectrum;
25702 if (is_invert) cimg_forC(real,c) { ptrr-=off; ptri-=off; *ptri = (T)(*(--ptrd)/fact); *ptrr = (T)(*(--ptrd)/fact); }
25703 else cimg_forC(real,c) { ptrr-=off; ptri-=off; *ptri = (T)*(--ptrd); *ptrr = (T)*(--ptrd); }
25707 fftw_destroy_plan(data_plan);
25708 fftw_free(data_in);
25712 const unsigned int N = real._width, N2 = (N>>1);
25713 if (((N-1)&N) && N!=1)
25714 throw CImgInstanceException(
"CImgList<%s>::FFT(): Specified real and imaginary parts (%u,%u,%u,%u) have non 2^N dimension along the X-axis.",
25716 real._width,real._height,real._depth,real._spectrum);
25718 for (
unsigned int i = 0, j = 0; i<N2; ++i) {
25719 if (j>i) cimg_forYZC(real,y,z,c) {
25720 cimg::swap(real(i,y,z,c),real(j,y,z,c));
cimg::swap(imag(i,y,z,c),imag(j,y,z,c));
25722 const unsigned int ri = N-1-i, rj = N-1-j;
25723 cimg::swap(real(ri,y,z,c),real(rj,y,z,c));
cimg::swap(imag(ri,y,z,c),imag(rj,y,z,c));
25726 for (
unsigned int m = N, n = N2; (j+=n)>=m; j-=m, m = n, n>>=1) {}
25728 for (
unsigned int delta = 2; delta<=N; delta<<=1) {
25729 const unsigned int delta2 = (delta>>1);
25730 for (
unsigned int i = 0; i<N; i+=delta) {
25731 float wr = 1, wi = 0;
25732 const float angle = (float)((is_invert?+1:-1)*2*
cimg::PI/delta),
25733 ca = (
float)std::cos(angle),
25734 sa = (float)std::sin(angle);
25735 for (
unsigned int k = 0; k<delta2; ++k) {
25736 const unsigned int j = i + k, nj = j + delta2;
25737 cimg_forYZC(real,y,z,c) {
25738 T &ir = real(j,y,z,c), &ii = imag(j,y,z,c), &nir = real(nj,y,z,c), &nii = imag(nj,y,z,c);
25739 const float tmpr = (float)(wr*nir - wi*nii), tmpi = (float)(wr*nii + wi*nir);
25740 nir = (T)(ir - tmpr);
25741 nii = (T)(ii - tmpi);
25745 const float nwr = wr*ca-wi*sa;
25746 wi = wi*ca + wr*sa;
25751 if (is_invert) { real/=N; imag/=N; }
25754 const unsigned int N = real._height, N2 = (N>>1);
25755 if (((N-1)&N) && N!=1)
25756 throw CImgInstanceException(
"CImgList<%s>::FFT(): Specified real and imaginary parts (%u,%u,%u,%u) have non 2^N dimension along the Y-axis.",
25758 real._width,real._height,real._depth,real._spectrum);
25760 for (
unsigned int i = 0, j = 0; i<N2; ++i) {
25761 if (j>i) cimg_forXZC(real,x,z,c) {
25762 cimg::swap(real(x,i,z,c),real(x,j,z,c));
cimg::swap(imag(x,i,z,c),imag(x,j,z,c));
25764 const unsigned int ri = N - 1 - i, rj = N - 1 - j;
25765 cimg::swap(real(x,ri,z,c),real(x,rj,z,c));
cimg::swap(imag(x,ri,z,c),imag(x,rj,z,c));
25768 for (
unsigned int m = N, n = N2; (j+=n)>=m; j-=m, m = n, n>>=1) {}
25770 for (
unsigned int delta = 2; delta<=N; delta<<=1) {
25771 const unsigned int delta2 = (delta>>1);
25772 for (
unsigned int i = 0; i<N; i+=delta) {
25773 float wr = 1, wi = 0;
25774 const float angle = (float)((is_invert?+1:-1)*2*
cimg::PI/delta),
25775 ca = (
float)std::cos(angle), sa = (float)std::sin(angle);
25776 for (
unsigned int k = 0; k<delta2; ++k) {
25777 const unsigned int j = i + k, nj = j + delta2;
25778 cimg_forXZC(real,x,z,c) {
25779 T &ir = real(x,j,z,c), &ii = imag(x,j,z,c), &nir = real(x,nj,z,c), &nii = imag(x,nj,z,c);
25780 const float tmpr = (float)(wr*nir - wi*nii), tmpi = (float)(wr*nii + wi*nir);
25781 nir = (T)(ir - tmpr);
25782 nii = (T)(ii - tmpi);
25786 const float nwr = wr*ca-wi*sa;
25787 wi = wi*ca + wr*sa;
25792 if (is_invert) { real/=N; imag/=N; }
25795 const unsigned int N = real._depth, N2 = (N>>1);
25796 if (((N-1)&N) && N!=1)
25797 throw CImgInstanceException(
"CImgList<%s>::FFT(): Specified real and imaginary parts (%u,%u,%u,%u) have non 2^N dimension along the Z-axis.",
25799 real._width,real._height,real._depth,real._spectrum);
25801 for (
unsigned int i = 0, j = 0; i<N2; ++i) {
25802 if (j>i) cimg_forXYC(real,x,y,c) {
25803 cimg::swap(real(x,y,i,c),real(x,y,j,c));
cimg::swap(imag(x,y,i,c),imag(x,y,j,c));
25805 const unsigned int ri = N - 1 - i, rj = N - 1 - j;
25806 cimg::swap(real(x,y,ri,c),real(x,y,rj,c));
cimg::swap(imag(x,y,ri,c),imag(x,y,rj,c));
25809 for (
unsigned int m = N, n = N2; (j+=n)>=m; j-=m, m = n, n>>=1) {}
25811 for (
unsigned int delta = 2; delta<=N; delta<<=1) {
25812 const unsigned int delta2 = (delta>>1);
25813 for (
unsigned int i = 0; i<N; i+=delta) {
25814 float wr = 1, wi = 0;
25815 const float angle = (float)((is_invert?+1:-1)*2*
cimg::PI/delta),
25816 ca = (
float)std::cos(angle), sa = (float)std::sin(angle);
25817 for (
unsigned int k = 0; k<delta2; ++k) {
25818 const unsigned int j = i + k, nj = j + delta2;
25819 cimg_forXYC(real,x,y,c) {
25820 T &ir = real(x,y,j,c), &ii = imag(x,y,j,c), &nir = real(x,y,nj,c), &nii = imag(x,y,nj,c);
25821 const float tmpr = (float)(wr*nir - wi*nii), tmpi = (float)(wr*nii + wi*nir);
25822 nir = (T)(ir - tmpr);
25823 nii = (T)(ii - tmpi);
25827 const float nwr = wr*ca-wi*sa;
25828 wi = wi*ca + wr*sa;
25833 if (is_invert) { real/=N; imag/=N; }
25836 throw CImgArgumentException(
"CImgList<%s>::FFT(): Invalid specified axis '%c' for real and imaginary parts (%u,%u,%u,%u) "
25837 "(should be { x | y | z }).",
25839 real._width,real._height,real._depth,real._spectrum);
25855 if (!imag) imag.assign(real._width,real._height,real._depth,real._spectrum,0);
25856 if (!real.is_sameXYZC(imag))
25857 throw CImgInstanceException(
"CImgList<%s>::FFT(): Specified real part (%u,%u,%u,%u,%p) and imaginary part (%u,%u,%u,%u,%p) have different dimensions.",
25859 real._width,real._height,real._depth,real._spectrum,real._data,
25860 imag._width,imag._height,imag._depth,imag._spectrum,imag._data);
25862 #ifdef cimg_use_fftw3
25863 fftw_complex *data_in = (fftw_complex*)fftw_malloc(
sizeof(fftw_complex)*real._width*real._height*real._depth);
25864 if (!data_in)
throw CImgInstanceException(
"CImgList<%s>::FFT(): Failed to allocate memory (%s) for computing FFT of image (%u,%u,%u,%u).",
25866 cimg::strbuffersize(
sizeof(fftw_complex)*real._width*real._height*real._depth*real._spectrum),
25867 real._width,real._height,real._depth,real._spectrum);
25869 fftw_plan data_plan;
25870 const unsigned long w = (
unsigned long)real._width, wh = w*real._height, whd = wh*real._depth;
25871 data_plan = fftw_plan_dft_3d(real._width,real._height,real._depth,data_in,data_in,is_invert?FFTW_BACKWARD:FFTW_FORWARD,FFTW_ESTIMATE);
25872 cimg_forC(real,c) {
25873 T *ptrr = real.data(0,0,0,c), *ptri = imag.data(0,0,0,c);
25874 double *ptrd = (
double*)data_in;
25875 for (
unsigned int x = 0; x<real._width; ++x, ptrr-=wh-1, ptri-=wh-1)
25876 for (
unsigned int y = 0; y<real._height; ++y, ptrr-=whd-w, ptri-=whd-w)
25877 for (
unsigned int z = 0; z<real._depth; ++z, ptrr+=wh, ptri+=wh) {
25878 *(ptrd++) = (
double)*ptrr; *(ptrd++) = (
double)*ptri;
25880 fftw_execute(data_plan);
25881 ptrd = (
double*)data_in;
25882 ptrr = real.data(0,0,0,c);
25883 ptri = imag.data(0,0,0,c);
25884 if (!is_invert)
for (
unsigned int x = 0; x<real._width; ++x, ptrr-=wh-1, ptri-=wh-1)
25885 for (
unsigned int y = 0; y<real._height; ++y, ptrr-=whd-w, ptri-=whd-w)
25886 for (
unsigned int z = 0; z<real._depth; ++z, ptrr+=wh, ptri+=wh) {
25887 *ptrr = (T)*(ptrd++); *ptri = (T)*(ptrd++);
25889 else for (
unsigned int x = 0; x<real._width; ++x, ptrr-=wh-1, ptri-=wh-1)
25890 for (
unsigned int y = 0; y<real._height; ++y, ptrr-=whd-w, ptri-=whd-w)
25891 for (
unsigned int z = 0; z<real._depth; ++z, ptrr+=wh, ptri+=wh) {
25892 *ptrr = (T)(*(ptrd++)/whd); *ptri = (T)(*(ptrd++)/whd);
25895 fftw_destroy_plan(data_plan);
25896 fftw_free(data_in);
25898 if (real._depth>1)
FFT(real,imag,
'z',is_invert);
25899 if (real._height>1)
FFT(real,imag,
'y',is_invert);
25900 if (real._width>1)
FFT(real,imag,
'x',is_invert);
25918 if (_height!=3 || _depth>1 || _spectrum>1)
25920 "shift_object3d(): Instance is not a set of 3d vertices.",
25937 if (_height!=3 || _depth>1 || _spectrum>1)
25939 "shift_object3d(): Instance is not a set of 3d vertices.",
25943 float xm, xM = (float)xcoords.max_min(xm), ym, yM = (float)ycoords.max_min(ym), zm, zM = (float)zcoords.max_min(zm);
25944 xcoords-=(xm + xM)/2; ycoords-=(ym + yM)/2; zcoords-=(zm + zM)/2;
25960 if (_height!=3 || _depth>1 || _spectrum>1)
25962 "resize_object3d(): Instance is not a set of 3d vertices.",
25966 float xm, xM = (float)xcoords.max_min(xm), ym, yM = (float)ycoords.max_min(ym), zm, zM = (float)zcoords.max_min(zm);
25967 if (xm<xM) {
if (sx>0) xcoords*=sx/(xM-xm);
else xcoords*=-sx/100; }
25968 if (ym<yM) {
if (sy>0) ycoords*=sy/(yM-ym);
else ycoords*=-sy/100; }
25969 if (zm<zM) {
if (sz>0) zcoords*=sz/(zM-zm);
else zcoords*=-sz/100; }
25980 if (_height!=3 || _depth>1 || _spectrum>1)
25982 "resize_object3d(): Instance is not a set of 3d vertices.",
25986 float xm, xM = (float)xcoords.max_min(xm), ym, yM = (float)ycoords.max_min(ym), zm, zM = (float)zcoords.max_min(zm);
25987 const float dx = xM - xm, dy = yM - ym, dz = zM - zm, dmax =
cimg::max(dx,dy,dz);
25988 if (dmax>0) { xcoords/=dmax; ycoords/=dmax; zcoords/=dmax; }
26003 template<
typename tf,
typename tp,
typename tff>
26005 if (!obj_vertices || !obj_primitives)
return *
this;
26006 if (obj_vertices._height!=3 || obj_vertices._depth>1 || obj_vertices._spectrum>1)
26008 "append_object3d(): Specified vertice image (%u,%u,%u,%u,%p) is not a set of 3d vertices.",
26010 obj_vertices._width,obj_vertices._height,obj_vertices._depth,obj_vertices._spectrum,obj_vertices._data);
26013 if (_height!=3 || _depth>1 || _spectrum>1)
26015 "append_object3d(): Instance is not a set of 3d vertices.",
26018 const unsigned int P = _width;
26019 append(obj_vertices,
'x');
26020 const unsigned int N = primitives._width;
26021 primitives.
insert(obj_primitives);
26022 for (
unsigned int i = N; i<primitives._width; ++i) {
26024 switch (p.size()) {
26025 case 1 : p[0]+=P;
break;
26026 case 5 : p[0]+=P; p[1]+=P;
break;
26027 case 2 :
case 6 : p[0]+=P; p[1]+=P;
break;
26028 case 3 :
case 9 : p[0]+=P; p[1]+=P; p[2]+=P;
break;
26029 case 4 :
case 12 : p[0]+=P; p[1]+=P; p[2]+=P; p[3]+=P;
break;
26042 template<
typename tp,
typename tc,
typename tt,
typename tx>
26048 "texturize_object3d(): image instance is not a set of 3d points.",
26050 if (coords && (coords._width!=_width || coords._height!=2))
26052 "texturize_object3d(): Invalid specified texture coordinates (%u,%u,%u,%u,%p).",
26054 coords._width,coords._height,coords._depth,coords._spectrum,coords._data);
26057 _coords.assign(_width,2);
26061 dx = xmax>xmin?xmax-xmin:1,
26062 dy = ymax>ymin?ymax-ymin:1;
26063 cimg_forX(*
this,p) {
26064 _coords(p,0) = (
unsigned int)(((*
this)(p,0)-xmin)*(texture._width-1)/dx);
26065 _coords(p,1) = (
unsigned int)(((*
this)(p,1)-ymin)*(texture._height-1)/dy);
26067 }
else _coords = coords;
26069 int texture_ind = -1;
26070 cimglist_for(primitives,l) {
26072 const unsigned int siz = p.size();
26076 i0 = (
unsigned int)p[0],
26077 x0 = (
unsigned int)_coords(i0,0), y0 = (
unsigned int)_coords(i0,1);
26078 texture.get_vector_at(x0,y0).move_to(colors[l]);
26080 case 2 :
case 6 : {
26082 i0 = (
unsigned int)p[0], i1 = (
unsigned int)p[1],
26083 x0 = (
unsigned int)_coords(i0,0), y0 = (
unsigned int)_coords(i0,1),
26084 x1 = (
unsigned int)_coords(i1,0), y1 = (
unsigned int)_coords(i1,1);
26085 if (texture_ind<0) colors[texture_ind=l] = texture;
else colors[l].
assign(colors[texture_ind],
true);
26088 case 3 :
case 9 : {
26090 i0 = (
unsigned int)p[0], i1 = (
unsigned int)p[1], i2 = (
unsigned int)p[2],
26091 x0 = (
unsigned int)_coords(i0,0), y0 = (
unsigned int)_coords(i0,1),
26092 x1 = (
unsigned int)_coords(i1,0), y1 = (
unsigned int)_coords(i1,1),
26093 x2 = (
unsigned int)_coords(i2,0), y2 = (
unsigned int)_coords(i2,1);
26094 if (texture_ind<0) colors[texture_ind=l] = texture;
else colors[l].
assign(colors[texture_ind],
true);
26097 case 4 :
case 12 : {
26099 i0 = (
unsigned int)p[0], i1 = (
unsigned int)p[1], i2 = (
unsigned int)p[2], i3 = (
unsigned int)p[3],
26100 x0 = (
unsigned int)_coords(i0,0), y0 = (
unsigned int)_coords(i0,1),
26101 x1 = (
unsigned int)_coords(i1,0), y1 = (
unsigned int)_coords(i1,1),
26102 x2 = (
unsigned int)_coords(i2,0), y2 = (
unsigned int)_coords(i2,1),
26103 x3 = (
unsigned int)_coords(i3,0), y3 = (
unsigned int)_coords(i3,1);
26104 if (texture_ind<0) colors[texture_ind=l] = texture;
else colors[l].
assign(colors[texture_ind],
true);
26105 CImg<tp>::vector(i0,i1,i2,i3,x0,y0,x1,y1,x2,y2,x3,y3).move_to(p);
26129 template<
typename tf,
typename tc,
typename te>
26131 if (!
is_sameXY(elevation) || elevation._depth>1 || elevation._spectrum>1)
26133 "get_elevation3d(): Instance and specified elevation (%u,%u,%u,%u,%p) "
26134 "have incompatible dimensions.",
26136 elevation._width,elevation._height,elevation._depth,elevation._spectrum,elevation._data);
26138 float m, M = (float)
max_min(m);
26141 const unsigned int size_x1 = _width - 1, size_y1 = _height - 1;
26142 for (
unsigned int y = 0; y<size_y1; ++y)
26143 for (
unsigned int x = 0; x<size_x1; ++x) {
26144 const unsigned char
26145 r = (
unsigned char)(((*
this)(x,y,0) - m)*255/(M-m)),
26146 g = _spectrum>1?(
unsigned char)(((*
this)(x,y,1) - m)*255/(M-m)):r,
26147 b = _spectrum>2?(
unsigned char)(((*
this)(x,y,2) - m)*255/(M-m)):(_spectrum>1?0:r);
26151 return elevation3d(primitives,func,0,0,_width-1.0f,_height-1.0f,_width,_height);
26163 template<
typename tf,
typename tc>
26165 const unsigned int x0,
const unsigned int y0,
const unsigned int z0,
26166 const bool normalize_colors=
false)
const {
26167 float m = 0, M = 0, delta = 1;
26168 if (normalize_colors) { m = (float)
min_max(M); delta = 255/(m==M?1:M-m); }
26170 _x0 = (x0>=_width)?_width - 1:x0,
26171 _y0 = (y0>=_height)?_height - 1:y0,
26172 _z0 = (z0>=_depth)?_depth - 1:z0;
26174 if (normalize_colors) {
26175 ((
get_crop(0,0,_z0,0,_width-1,_height-1,_z0,_spectrum-1)-=m)*=delta).
move_to(img_xy);
26176 ((
get_crop(0,_y0,0,0,_width-1,_y0,_depth-1,_spectrum-1)-=m)*=delta).resize(_width,_depth,1,-100,-1).move_to(img_xz);
26177 ((
get_crop(_x0,0,0,0,_x0,_height-1,_depth-1,_spectrum-1)-=m)*=delta).resize(_height,_depth,1,-100,-1).move_to(img_yz);
26179 get_crop(0,0,_z0,0,_width-1,_height-1,_z0,_spectrum-1).move_to(img_xy);
26180 get_crop(0,_y0,0,0,_width-1,_y0,_depth-1,_spectrum-1).resize(_width,_depth,1,-100,-1).move_to(img_xz);
26181 get_crop(_x0,0,0,0,_x0,_height-1,_depth-1,_spectrum-1).resize(_height,_depth,1,-100,-1).move_to(img_yz);
26184 0,_width-1,_width-1,0, 0,_width-1,_width-1,0, _x0,_x0,_x0,_x0,
26185 0,0,_height-1,_height-1, _y0,_y0,_y0,_y0, 0,_height-1,_height-1,0,
26186 _z0,_z0,_z0,_z0, 0,0,_depth-1,_depth-1, 0,0,_depth-1,_depth-1);
26188 CImg<tf>::vector(0,1,2,3,0,0,img_xy._width-1,0,img_xy._width-1,img_xy._height-1,0,img_xy._height-1).move_to(primitives);
26189 CImg<tf>::vector(4,5,6,7,0,0,img_xz._width-1,0,img_xz._width-1,img_xz._height-1,0,img_xz._height-1).move_to(primitives);
26190 CImg<tf>::vector(8,9,10,11,0,0,img_yz._width-1,0,img_yz._width-1,img_yz._height-1,0,img_yz._height-1).move_to(primitives);
26192 img_xy.move_to(colors);
26193 img_xz.move_to(colors);
26194 img_yz.move_to(colors);
26215 template<
typename tf>
26217 const int size_x=-100,
const int size_y=-100)
const {
26220 "get_isoline3d(): Instance is not a scalar image.",
26224 "get_isoline3d(): Instance is not a 2d image.",
26229 if ((size_x==-100 && size_y==-100) || (size_x==
width() && size_y==
height())) {
26230 const _functor2d_int func(*
this);
26233 const _functor2d_float func(*
this);
26257 template<
typename tf>
26259 const int size_x=-100,
const int size_y=-100,
const int size_z=-100)
const {
26262 "get_isosurface3d(): Instance is not a scalar image.",
26267 if ((size_x==-100 && size_y==-100 && size_z==-100) || (size_x==
width() && size_y==
height() && size_z==
depth())) {
26268 const _functor3d_int func(*
this);
26269 vertices =
isosurface3d(primitives,func,isovalue,0,0,0,
width()-1.0f,
height()-1.0f,
depth()-1.0f,
width(),
height(),
depth());
26271 const _functor3d_float func(*
this);
26272 vertices =
isosurface3d(primitives,func,isovalue,0,0,0,
width()-1.0f,
height()-1.0f,
depth()-1.0f,size_x,size_y,size_z);
26288 template<
typename tf,
typename tfunc>
26290 const float x0,
const float y0,
const float x1,
const float y1,
26291 const int size_x=256,
const int size_y=256) {
26293 nx0 = x0<x1?x0:x1, ny0 = y0<y1?y0:y1,
26294 nx1 = x0<x1?x1:x0, ny1 = y0<y1?y1:y0;
26296 _nsize_x = (
unsigned int)(size_x>=0?size_x:(nx1-nx0)*-size_x/100), nsize_x = _nsize_x?_nsize_x:1, nsize_x1 = nsize_x - 1,
26297 _nsize_y = (
unsigned int)(size_y>=0?size_y:(ny1-ny0)*-size_y/100), nsize_y = _nsize_y?_nsize_y:1, nsize_y1 = nsize_y - 1;
26298 if (nsize_x<2 || nsize_y<2)
26304 floatT *ptr_x = vertices.
data(0,0), *ptr_y = vertices.
data(0,1), *ptr_z = vertices.
data(0,2);
26305 for (
unsigned int y = 0; y<nsize_y; ++y) {
26306 const float Y = ny0 + y*(ny1-ny0)/nsize_y1;
26307 for (
unsigned int x = 0; x<nsize_x; ++x) {
26308 const float X = nx0 + x*(nx1-nx0)/nsize_x1;
26309 *(ptr_x++) = (
float)x;
26310 *(ptr_y++) = (
float)y;
26311 *(ptr_z++) = (
float)func(X,Y);
26314 primitives.
assign(nsize_x1*nsize_y1,1,4);
26315 for (
unsigned int p = 0, y = 0; y<nsize_y1; ++y) {
26316 const unsigned int yw = y*nsize_x;
26317 for (
unsigned int x = 0; x<nsize_x1; ++x) {
26318 const unsigned int xpyw = x + yw, xpyww = xpyw + nsize_x;
26319 primitives[p++].fill(xpyw,xpyww,xpyww+1,xpyw+1);
26326 template<
typename tf>
26328 const float x0,
const float y0,
const float x1,
const float y1,
26329 const int size_x=256,
const int size_y=256) {
26330 const _functor2d_expr func(expression);
26331 return elevation3d(primitives,func,x0,y0,x1,y1,size_x,size_y);
26347 template<
typename tf,
typename tfunc>
26349 const float x0,
const float y0,
const float x1,
const float y1,
26350 const int size_x=256,
const int size_y=256) {
26351 static const unsigned int edges[16] = { 0x0, 0x9, 0x3, 0xa, 0x6, 0xf, 0x5, 0xc, 0xc, 0x5, 0xf, 0x6, 0xa, 0x3, 0x9, 0x0 };
26352 static const int segments[16][4] = { { -1,-1,-1,-1 }, { 0,3,-1,-1 }, { 0,1,-1,-1 }, { 1,3,-1,-1 },
26353 { 1,2,-1,-1 }, { 0,1,2,3 }, { 0,2,-1,-1 }, { 2,3,-1,-1 },
26354 { 2,3,-1,-1 }, { 0,2,-1,-1}, { 0,3,1,2 }, { 1,2,-1,-1 },
26355 { 1,3,-1,-1 }, { 0,1,-1,-1}, { 0,3,-1,-1}, { -1,-1,-1,-1 } };
26357 _nx = (
unsigned int)(size_x>=0?size_x:
cimg::round((x1-x0)*-size_x/100 + 1)),
26358 _ny = (
unsigned int)(size_y>=0?size_y:
cimg::round((y1-y0)*-size_y/100 + 1)),
26365 const float dx = (x1 - x0)/nxm1, dy = (y1 - y0)/nym1;
26367 CImg<intT> indices1(nx,1,1,2,-1), indices2(nx,1,1,2);
26369 float X = x0, Y = y0, nX = X + dx, nY = Y + dy;
26372 cimg_forX(values1,x) { values1(x) = (float)func(X,Y); X+=dx; }
26375 for (
unsigned int yi = 0, nyi = 1; yi<nym1; ++yi, ++nyi, Y=nY, nY+=dy) {
26376 X = x0; nX = X + dx;
26378 for (
unsigned int xi = 0, nxi = 1; xi<nxm1; ++xi, ++nxi, X=nX, nX+=dx) {
26382 val0 = values1(xi),
26383 val1 = values1(nxi),
26384 val2 = values2(nxi) = (float)func(nX,nY),
26385 val3 = values2(xi) = (float)func(X,nY);
26387 configuration = (val0<isovalue?1:0) | (val1<isovalue?2:0) | (val2<isovalue?4:0) | (val3<isovalue?8:0),
26388 edge = edges[configuration];
26392 if ((edge&1) && indices1(xi,0)<0) {
26393 const float Xi = X + (isovalue-val0)*dx/(val1-val0);
26394 indices1(xi,0) = vertices._width;
26397 if ((edge&2) && indices1(nxi,1)<0) {
26398 const float Yi = Y + (isovalue-val1)*dy/(val2-val1);
26399 indices1(nxi,1) = vertices._width;
26402 if ((edge&4) && indices2(xi,0)<0) {
26403 const float Xi = X + (isovalue-val3)*dx/(val2-val3);
26404 indices2(xi,0) = vertices._width;
26407 if ((edge&8) && indices1(xi,1)<0) {
26408 const float Yi = Y + (isovalue-val0)*dy/(val3-val0);
26409 indices1(xi,1) = vertices._width;
26414 for (
const int *segment = segments[configuration]; *segment!=-1; ) {
26415 const unsigned int p0 = *(segment++), p1 = *(segment++);
26417 i0 = (tf)(_isoline3d_indice(p0,indices1,indices2,xi,nxi)),
26418 i1 = (tf)(_isoline3d_indice(p1,indices1,indices2,xi,nxi));
26423 values1.swap(values2);
26424 indices1.swap(indices2);
26426 return vertices>
'x';
26430 template<
typename tf>
26432 const float x0,
const float y0,
const float x1,
const float y1,
26433 const int size_x=256,
const int size_y=256) {
26434 const _functor2d_expr func(expression);
26435 return isoline3d(primitives,func,isovalue,x0,y0,x1,y1,size_x,size_y);
26438 template<
typename t>
26439 static int _isoline3d_indice(
const unsigned int edge,
const CImg<t>& indices1,
const CImg<t>& indices2,
26440 const unsigned int x,
const unsigned int nx) {
26442 case 0 :
return (
int)indices1(x,0);
26443 case 1 :
return (
int)indices1(nx,1);
26444 case 2 :
return (
int)indices2(x,0);
26445 case 3 :
return (
int)indices1(x,1);
26466 template<
typename tf,
typename tfunc>
26468 const float x0,
const float y0,
const float z0,
26469 const float x1,
const float y1,
const float z1,
26470 const int size_x=32,
const int size_y=32,
const int size_z=32) {
26471 static unsigned int edges[256] = {
26472 0x000, 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
26473 0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
26474 0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c, 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
26475 0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac, 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
26476 0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c, 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
26477 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc, 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
26478 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c, 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
26479 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc , 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
26480 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc, 0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
26481 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c, 0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
26482 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc, 0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
26483 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c, 0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460,
26484 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac, 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0,
26485 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c, 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230,
26486 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c, 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190,
26487 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c, 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x000 };
26489 static int triangles[256][16] = {
26490 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26491 { 0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26492 { 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26493 { 9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1 },
26494 { 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26495 { 1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1 },
26496 { 3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1 },
26497 { 3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1 }, { 9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26498 { 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26499 { 0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1 },
26500 { 1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1 },
26501 { 9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1 }, { 2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1 },
26502 { 8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1 },
26503 { 9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1 }, { 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1 },
26504 { 3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1 }, { 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1 },
26505 { 4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1 }, { 4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1 },
26506 { 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26507 { 0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1 },
26508 { 1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1 },
26509 { 5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1 }, { 2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1 },
26510 { 9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1 },
26511 { 0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1 }, { 2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1 },
26512 { 10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1 }, { 4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1 },
26513 { 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1 }, { 5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1 },
26514 { 9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1 },
26515 { 0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1 }, { 1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26516 { 9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1 }, { 10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1 },
26517 { 8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1 }, { 2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1 },
26518 { 7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1 }, { 9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1 },
26519 { 2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1 }, { 11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1 },
26520 { 9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1 }, { 5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1 },
26521 { 11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1 }, { 11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26522 { 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26523 { 9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1 },
26524 { 1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1 },
26525 { 9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1 }, { 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1 },
26526 { 2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1 },
26527 { 0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1 }, { 5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1 },
26528 { 6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1 }, { 0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1 },
26529 { 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1 }, { 6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1 },
26530 { 5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1 },
26531 { 1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1 }, { 10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1 },
26532 { 6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1 }, { 1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1 },
26533 { 8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1 }, { 7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1 },
26534 { 3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1 }, { 5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1 },
26535 { 0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1 }, { 9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1 },
26536 { 8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1 }, { 5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1 },
26537 { 0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1 }, { 6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1 },
26538 { 10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1 },
26539 { 10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1 }, { 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1 },
26540 { 1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1 }, { 3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1 },
26541 { 0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1 },
26542 { 10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1 }, { 0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1 },
26543 { 3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1 }, { 6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1 },
26544 { 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1 }, { 8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1 },
26545 { 3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1 }, { 6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26546 { 7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1 }, { 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1 },
26547 { 10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1 }, { 10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1 },
26548 { 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1 }, { 2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1 },
26549 { 7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1 }, { 7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26550 { 2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1 }, { 2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1 },
26551 { 1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1 }, { 11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1 },
26552 { 8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1 }, { 0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26553 { 7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1 }, { 7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26554 { 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26555 { 0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1 },
26556 { 10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1 },
26557 { 2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1 }, { 6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1 },
26558 { 7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1 },
26559 { 2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1 }, { 1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1 },
26560 { 10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1 }, { 10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1 },
26561 { 0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1 }, { 7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1 },
26562 { 6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1 },
26563 { 8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1 }, { 9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1 },
26564 { 6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1 }, { 1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1 },
26565 { 4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1 }, { 10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1 },
26566 { 8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1 }, { 0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26567 { 1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1 }, { 1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1 },
26568 { 8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1 }, { 10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1 },
26569 { 4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1 }, { 10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26570 { 4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1 },
26571 { 5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1 }, { 11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1 },
26572 { 9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1 }, { 6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1 },
26573 { 7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1 }, { 3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1 },
26574 { 7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1 }, { 9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1 },
26575 { 3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1 }, { 6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1 },
26576 { 9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1 }, { 1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1 },
26577 { 4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1 }, { 7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1 },
26578 { 6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1 }, { 3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1 },
26579 { 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1 }, { 6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1 },
26580 { 1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1 }, { 0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1 },
26581 { 11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1 }, { 6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1 },
26582 { 5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1 }, { 9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1 },
26583 { 1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1 }, { 1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26584 { 1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1 }, { 10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1 },
26585 { 0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26586 { 11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1 },
26587 { 5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1 }, { 10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1 },
26588 { 11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1 }, { 0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1 },
26589 { 9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1 }, { 7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1 },
26590 { 2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1 }, { 8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1 },
26591 { 9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1 }, { 9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1 },
26592 { 1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1 },
26593 { 9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1 }, { 9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26594 { 5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1 }, { 5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1 },
26595 { 0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1 }, { 10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1 },
26596 { 2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1 }, { 0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1 },
26597 { 0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1 }, { 9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26598 { 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1 }, { 5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1 },
26599 { 3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1 }, { 5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1 },
26600 { 8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1 }, { 0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26601 { 8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1 }, { 9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26602 { 4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1 }, { 0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1 },
26603 { 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1 }, { 3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1 },
26604 { 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1 }, { 9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1 },
26605 { 11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1 }, { 11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1 },
26606 { 2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1 }, { 9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1 },
26607 { 3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1 }, { 1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26608 { 4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1 }, { 4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1 },
26609 { 4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26610 { 9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1 },
26611 { 0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1 }, { 3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26612 { 1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1 }, { 3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1 },
26613 { 0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26614 { 2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1 }, { 9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26615 { 2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1 }, { 1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26616 { 1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
26617 { 0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }
26621 _nx = (
unsigned int)(size_x>=0?size_x:
cimg::round((x1-x0)*-size_x/100 + 1)),
26622 _ny = (
unsigned int)(size_y>=0?size_y:
cimg::round((y1-y0)*-size_y/100 + 1)),
26623 _nz = (
unsigned int)(size_z>=0?size_z:
cimg::round((z1-z0)*-size_z/100 + 1)),
26632 const float dx = (x1 - x0)/nxm1, dy = (y1 - y0)/nym1, dz = (z1 - z0)/nzm1;
26634 CImg<intT> indices1(nx,ny,1,3,-1), indices2(indices1);
26636 float X = 0, Y = 0, Z = 0, nX = 0, nY = 0, nZ = 0;
26640 cimg_forY(values1,y) {
26642 cimg_forX(values1,x) { values1(x,y) = (float)func(X,Y,z0); X+=dx; }
26647 Z = z0; nZ = Z + dz;
26648 for (
unsigned int zi = 0; zi<nzm1; ++zi, Z = nZ, nZ+=dz) {
26649 Y = y0; nY = Y + dy;
26651 for (
unsigned int yi = 0, nyi = 1; yi<nym1; ++yi, ++nyi, Y = nY, nY+=dy) {
26652 X = x0; nX = X + dx;
26653 for (
unsigned int xi = 0, nxi = 1; xi<nxm1; ++xi, ++nxi, X = nX, nX+=dx) {
26657 val0 = values1(xi,yi),
26658 val1 = values1(nxi,yi),
26659 val2 = values1(nxi,nyi),
26660 val3 = values1(xi,nyi),
26661 val4 = values2(xi,yi) = (float)func(X,Y,nZ),
26662 val5 = values2(nxi,yi) = (float)func(nX,Y,nZ),
26663 val6 = values2(nxi,nyi) = (float)func(nX,nY,nZ),
26664 val7 = values2(xi,nyi) = (float)func(X,nY,nZ);
26666 const unsigned int configuration =
26667 (val0<isovalue?1:0) | (val1<isovalue?2:0) | (val2<isovalue?4:0) | (val3<isovalue?8:0) |
26668 (val4<isovalue?16:0) | (val5<isovalue?32:0) | (val6<isovalue?64:0) | (val7<isovalue?128:0),
26669 edge = edges[configuration];
26673 if ((edge&1) && indices1(xi,yi,0)<0) {
26674 const float Xi = X + (isovalue-val0)*dx/(val1-val0);
26675 indices1(xi,yi,0) = vertices._width;
26678 if ((edge&2) && indices1(nxi,yi,1)<0) {
26679 const float Yi = Y + (isovalue-val1)*dy/(val2-val1);
26680 indices1(nxi,yi,1) = vertices._width;
26683 if ((edge&4) && indices1(xi,nyi,0)<0) {
26684 const float Xi = X + (isovalue-val3)*dx/(val2-val3);
26685 indices1(xi,nyi,0) = vertices._width;
26688 if ((edge&8) && indices1(xi,yi,1)<0) {
26689 const float Yi = Y + (isovalue-val0)*dy/(val3-val0);
26690 indices1(xi,yi,1) = vertices._width;
26693 if ((edge&16) && indices2(xi,yi,0)<0) {
26694 const float Xi = X + (isovalue-val4)*dx/(val5-val4);
26695 indices2(xi,yi,0) = vertices._width;
26698 if ((edge&32) && indices2(nxi,yi,1)<0) {
26699 const float Yi = Y + (isovalue-val5)*dy/(val6-val5);
26700 indices2(nxi,yi,1) = vertices._width;
26703 if ((edge&64) && indices2(xi,nyi,0)<0) {
26704 const float Xi = X + (isovalue-val7)*dx/(val6-val7);
26705 indices2(xi,nyi,0) = vertices._width;
26708 if ((edge&128) && indices2(xi,yi,1)<0) {
26709 const float Yi = Y + (isovalue-val4)*dy/(val7-val4);
26710 indices2(xi,yi,1) = vertices._width;
26713 if ((edge&256) && indices1(xi,yi,2)<0) {
26714 const float Zi = Z+ (isovalue-val0)*dz/(val4-val0);
26715 indices1(xi,yi,2) = vertices._width;
26718 if ((edge&512) && indices1(nxi,yi,2)<0) {
26719 const float Zi = Z + (isovalue-val1)*dz/(val5-val1);
26720 indices1(nxi,yi,2) = vertices._width;
26723 if ((edge&1024) && indices1(nxi,nyi,2)<0) {
26724 const float Zi = Z + (isovalue-val2)*dz/(val6-val2);
26725 indices1(nxi,nyi,2) = vertices._width;
26728 if ((edge&2048) && indices1(xi,nyi,2)<0) {
26729 const float Zi = Z + (isovalue-val3)*dz/(val7-val3);
26730 indices1(xi,nyi,2) = vertices._width;
26735 for (
const int *triangle = triangles[configuration]; *triangle!=-1; ) {
26736 const unsigned int p0 = *(triangle++), p1 = *(triangle++), p2 = *(triangle++);
26738 i0 = (tf)(_isosurface3d_indice(p0,indices1,indices2,xi,yi,nxi,nyi)),
26739 i1 = (tf)(_isosurface3d_indice(p1,indices1,indices2,xi,yi,nxi,nyi)),
26740 i2 = (tf)(_isosurface3d_indice(p2,indices1,indices2,xi,yi,nxi,nyi));
26749 return vertices>
'x';
26753 template<
typename tf>
26755 const float x0,
const float y0,
const float z0,
26756 const float x1,
const float y1,
const float z1,
26757 const int dx=32,
const int dy=32,
const int dz=32) {
26758 const _functor3d_expr func(expression);
26759 return isosurface3d(primitives,func,isovalue,x0,y0,z0,x1,y1,z1,dx,dy,dz);
26762 template<
typename t>
26763 static int _isosurface3d_indice(
const unsigned int edge,
const CImg<t>& indices1,
const CImg<t>& indices2,
26764 const unsigned int x,
const unsigned int y,
const unsigned int nx,
const unsigned int ny) {
26766 case 0 :
return indices1(x,y,0);
26767 case 1 :
return indices1(nx,y,1);
26768 case 2 :
return indices1(x,ny,0);
26769 case 3 :
return indices1(x,y,1);
26770 case 4 :
return indices2(x,y,0);
26771 case 5 :
return indices2(nx,y,1);
26772 case 6 :
return indices2(x,ny,0);
26773 case 7 :
return indices2(x,y,1);
26774 case 8 :
return indices1(x,y,2);
26775 case 9 :
return indices1(nx,y,2);
26776 case 10 :
return indices1(nx,ny,2);
26777 case 11 :
return indices1(x,ny,2);
26786 float operator()(
const float x,
const float y)
const {
26787 return (
float)ref((
int)x,(
int)y);
26794 float operator()(
const float x,
const float y)
const {
26795 return (
float)ref._linear_atXY(x,y);
26803 float operator()(
const float x,
const float y)
const {
26804 return (
float)mp->eval(x,y,0,0);
26811 float operator()(
const float x,
const float y,
const float z)
const {
26812 return (
float)ref((
int)x,(
int)y,(
int)z);
26819 float operator()(
const float x,
const float y,
const float z)
const {
26820 return (
float)ref._linear_atXYZ(x,y,z);
26828 float operator()(
const float x,
const float y,
const float z)
const {
26829 return (
float)mp->eval(x,y,z,0);
26836 float operator()(
const float x,
const float y,
const float z,
const unsigned int c)
const {
26837 return (
float)ref((
int)x,(
int)y,(
int)z,c);
26857 template<
typename tf>
26859 const float size_x=200,
const float size_y=100,
const float size_z=100) {
26860 primitives.
assign(6,1,4,1,1, 0,3,2,1, 4,5,6,7, 0,1,5,4, 3,7,6,2, 0,4,7,3, 1,2,6,5);
26862 0.,size_x,size_x, 0., 0.,size_x,size_x, 0.,
26863 0., 0.,size_y,size_y, 0., 0.,size_y,size_y,
26864 0., 0., 0., 0.,size_z,size_z,size_z,size_z);
26883 template<
typename tf>
26885 const float radius=50,
const float size_z=100,
const unsigned int subdivisions=24) {
26891 for (
float delta = 360.0f/subdivisions, angle = 0; angle<360; angle+=delta) {
26892 const float a = (float)(angle*
cimg::PI/180);
26893 CImg<floatT>::vector((
float)(radius*std::cos(a)),(
float)(radius*std::sin(a)),0).move_to(vertices);
26895 const unsigned int nbr = vertices._width - 2;
26896 for (
unsigned int p = 0; p<nbr; ++p) {
26897 const unsigned int curr = 2 + p, next = 2 + ((p+1)%nbr);
26901 return vertices>
'x';
26920 template<
typename tf>
26922 const float radius=50,
const float size_z=100,
const unsigned int subdivisions=24) {
26928 for (
float delta = 360.0f/subdivisions, angle = 0; angle<360; angle+=delta) {
26929 const float a = (float)(angle*
cimg::PI/180);
26930 CImg<floatT>::vector((
float)(radius*std::cos(a)),(
float)(radius*std::sin(a)),0.0f).move_to(vertices);
26931 CImg<floatT>::vector((
float)(radius*std::cos(a)),(
float)(radius*std::sin(a)),size_z).move_to(vertices);
26933 const unsigned int nbr = (vertices._width - 2)/2;
26934 for (
unsigned int p = 0; p<nbr; ++p) {
26935 const unsigned int curr = 2+2*p, next = 2+(2*((p+1)%nbr));
26940 return vertices>
'x';
26960 template<
typename tf>
26962 const float radius1=100,
const float radius2=30,
26963 const unsigned int subdivisions1=24,
const unsigned int subdivisions2=12) {
26965 if (!subdivisions1 || !subdivisions2)
return CImg<floatT>();
26967 for (
unsigned int v = 0; v<subdivisions1; ++v) {
26969 beta = (float)(v*2*
cimg::PI/subdivisions1),
26970 xc = radius1*(float)std::cos(beta),
26971 yc = radius1*(float)std::sin(beta);
26972 for (
unsigned int u = 0; u<subdivisions2; ++u) {
26974 alpha = (float)(u*2*
cimg::PI/subdivisions2),
26975 x = xc + radius2*(float)(std::cos(alpha)*std::cos(beta)),
26976 y = yc + radius2*(
float)(std::cos(alpha)*std::sin(beta)),
26977 z = radius2*(
float)std::sin(alpha);
26981 for (
unsigned int vv = 0; vv<subdivisions1; ++vv) {
26982 const unsigned int nv = (vv+1)%subdivisions1;
26983 for (
unsigned int uu = 0; uu<subdivisions2; ++uu) {
26984 const unsigned int nu = (uu+1)%subdivisions2, svv = subdivisions2*vv, snv = subdivisions2*nv;
26988 return vertices>
'x';
27008 template<
typename tf>
27010 const float size_x=100,
const float size_y=100,
27011 const unsigned int subdivisions_x=10,
const unsigned int subdivisions_y=10) {
27013 if (!subdivisions_x || !subdivisions_y)
return CImg<floatT>();
27015 const unsigned int w = subdivisions_x + 1, h = subdivisions_y + 1;
27016 const float fx = (float)size_x/w, fy = (
float)size_y/h;
27017 for (
unsigned int y = 0; y<h; ++y)
for (
unsigned int x = 0; x<w; ++x)
27019 for (
unsigned int y = 0; y<subdivisions_y; ++y)
for (
unsigned int x = 0; x<subdivisions_x; ++x) {
27020 const int off1 = x+y*w, off2 = x+1+y*w, off3 = x+1+(y+1)*w, off4 = x+(y+1)*w;
27023 return vertices>
'x';
27041 template<
typename tf>
27043 const float radius=50,
const unsigned int subdivisions=3) {
27047 const double tmp = (1+std::sqrt(5.0f))/2, a = 1.0/std::sqrt(1+tmp*tmp), b = tmp*a;
27048 CImgList<floatT> vertices(12,1,3,1,1, b,a,0.0, -b,a,0.0, -b,-a,0.0, b,-a,0.0, a,0.0,b, a,0.0,-b,
27049 -a,0.0,-b, -a,0.0,b, 0.0,b,a, 0.0,-b,a, 0.0,-b,-a, 0.0,b,-a);
27050 primitives.
assign(20,1,3,1,1, 4,8,7, 4,7,9, 5,6,11, 5,10,6, 0,4,3, 0,3,5, 2,7,1, 2,1,6,
27051 8,0,11, 8,11,1, 9,10,3, 9,2,10, 8,4,0, 11,0,5, 4,9,3,
27052 5,3,10, 7,8,1, 6,1,11, 7,2,9, 6,10,2);
27054 float he = (float)a;
27057 for (
unsigned int i = 0; i<subdivisions; ++i) {
27058 const unsigned int L = primitives._width;
27060 const float he2 = he*he;
27061 for (
unsigned int l = 0; l<L; ++l) {
27063 p0 = (
unsigned int)primitives(0,0), p1 = (
unsigned int)primitives(0,1), p2 = (
unsigned int)primitives(0,2);
27065 x0 = vertices(p0,0), y0 = vertices(p0,1), z0 = vertices(p0,2),
27066 x1 = vertices(p1,0), y1 = vertices(p1,1), z1 = vertices(p1,2),
27067 x2 = vertices(p2,0), y2 = vertices(p2,1), z2 = vertices(p2,2),
27068 tnx0 = (x0+x1)/2, tny0 = (y0+y1)/2, tnz0 = (z0+z1)/2, nn0 = (
float)std::sqrt(tnx0*tnx0+tny0*tny0+tnz0*tnz0),
27069 tnx1 = (x0+x2)/2, tny1 = (y0+y2)/2, tnz1 = (z0+z2)/2, nn1 = (
float)std::sqrt(tnx1*tnx1+tny1*tny1+tnz1*tnz1),
27070 tnx2 = (x1+x2)/2, tny2 = (y1+y2)/2, tnz2 = (z1+z2)/2, nn2 = (
float)std::sqrt(tnx2*tnx2+tny2*tny2+tnz2*tnz2),
27071 nx0 = tnx0/nn0, ny0 = tny0/nn0, nz0 = tnz0/nn0,
27072 nx1 = tnx1/nn1, ny1 = tny1/nn1, nz1 = tnz1/nn1,
27073 nx2 = tnx2/nn2, ny2 = tny2/nn2, nz2 = tnz2/nn2;
27074 int i0 = -1, i1 = -1, i2 = -1;
27075 cimglist_for(vertices,p) {
27076 const float x = (float)vertices(p,0), y = (float)vertices(p,1), z = (float)vertices(p,2);
27091 return (vertices>
'x')*=radius;
27110 template<
typename tf,
typename t>
27112 const CImg<t>&
tensor,
const unsigned int subdivisions=3) {
27116 tensor.symmetric_eigen(S,V);
27117 const float orient =
27118 (V(0,1)*V(1,2) - V(0,2)*V(1,1))*V(2,0) +
27119 (V(0,2)*V(1,0) - V(0,0)*V(1,2))*V(2,1) +
27120 (V(0,0)*V(1,1) - V(0,1)*V(1,0))*V(2,2);
27121 if (orient<0) { V(2,0) = -V(2,0); V(2,1) = -V(2,1); V(2,2) = -V(2,2); }
27122 const float l0 = S[0], l1 = S[1], l2 = S[2];
27136 template<
typename tp,
typename tc,
typename to>
27139 const to& opacities) {
27144 template<
typename tp,
typename tc>
27151 template<
typename tp>
27162 template<
typename tp,
typename tc,
typename to>
27165 const to& opacities)
const {
27166 char error_message[1024] = { 0 };
27167 if (!
is_object3d(primitives,colors,opacities,
true,error_message))
27169 "object3dtoCImg3d(): Invalid specified 3d object (%u,%u) (%s).",
27170 cimg_instance,_width,primitives._width,error_message);
27171 CImg<floatT> res(1,_size_object3dtoCImg3d(primitives,colors,opacities));
27172 float *ptrd = res._data;
27175 *(ptrd++) =
'C' + 0.5f; *(ptrd++) =
'I' + 0.5f; *(ptrd++) =
'm' + 0.5f;
27176 *(ptrd++) =
'g' + 0.5f; *(ptrd++) =
'3' + 0.5f; *(ptrd++) =
'd' + 0.5f;
27179 *(ptrd++) = cimg::uint2float(_width);
27180 *(ptrd++) = cimg::uint2float(primitives._width);
27183 if (
is_empty() || !primitives)
return res;
27184 const T *ptrx =
data(0,0), *ptry =
data(0,1), *ptrz =
data(0,2);
27185 cimg_forX(*
this,p) {
27186 *(ptrd++) = (
float)*(ptrx++);
27187 *(ptrd++) = (
float)*(ptry++);
27188 *(ptrd++) = (
float)*(ptrz++);
27192 cimglist_for(primitives,p) {
27193 *(ptrd++) = (
float)primitives[p].
size();
27194 const tp *ptrp = primitives[p]._data;
27195 cimg_foroff(primitives[p],i) *(ptrd++) = cimg::uint2float((
unsigned int)*(ptrp++));
27199 const unsigned int csiz =
cimg::min(colors._width,primitives._width);
27200 for (
int c = 0; c<(int)csiz; ++c) {
27201 const CImg<tc>& color = colors[c];
27202 const tc *ptrc = color._data;
27203 if (color.size()==3) { *(ptrd++) = (
float)*(ptrc++); *(ptrd++) = (
float)*(ptrc++); *(ptrd++) = (
float)*ptrc; }
27205 *(ptrd++) = -128.0f;
27206 int shared_ind = -1;
27207 if (color.is_shared())
for (
int i = 0; i<c; ++i)
if (ptrc==colors[i]._data) { shared_ind = i;
break; }
27208 if (shared_ind<0) {
27209 *(ptrd++) = (
float)color._width;
27210 *(ptrd++) = (
float)color._height;
27211 *(ptrd++) = (
float)color._spectrum;
27212 cimg_foroff(color,l) *(ptrd++) = (
float)*(ptrc++);
27214 *(ptrd++) = (
float)shared_ind;
27220 const int csiz2 = primitives._width - colors._width;
27221 for (
int c = 0; c<csiz2; ++c) { *(ptrd++) = 200.0f; *(ptrd++) = 200.0f; *(ptrd++) = 200.0f; }
27224 ptrd = _object3dtoCImg3d(opacities,ptrd);
27225 const float *ptre = res.
end();
27226 while (ptrd<ptre) *(ptrd++) = 1.0f;
27230 template<
typename to>
27231 float* _object3dtoCImg3d(
const CImgList<to>& opacities,
float *ptrd)
const {
27232 cimglist_for(opacities,o) {
27233 const CImg<to>& opacity = opacities[o];
27234 const to *ptro = opacity._data;
27235 if (opacity.size()==1) *(ptrd++) = (float)*ptro;
27237 *(ptrd++) = -128.0f;
27238 int shared_ind = -1;
27239 if (opacity.is_shared())
for (
int i = 0; i<o; ++i)
if (ptro==opacities[i]._data) { shared_ind = i;
break; }
27240 if (shared_ind<0) {
27241 *(ptrd++) = (
float)opacity._width;
27242 *(ptrd++) = (
float)opacity._height;
27243 *(ptrd++) = (
float)opacity._spectrum;
27244 cimg_foroff(opacity,l) *(ptrd++) = (
float)*(ptro++);
27246 *(ptrd++) = (
float)shared_ind;
27255 template<
typename to>
27256 float* _object3dtoCImg3d(
const CImg<to>& opacities,
float *ptrd)
const {
27257 const to *ptro = opacities._data;
27258 cimg_foroff(opacities,o) *(ptrd++) = (
float)*(ptro++);
27262 template<
typename tp,
typename tc,
typename to>
27263 unsigned int _size_object3dtoCImg3d(
const CImgList<tp>& primitives,
27264 const CImgList<tc>& colors,
27265 const CImgList<to>& opacities)
const {
27266 unsigned int siz = 8 + 3*
width();
27267 cimglist_for(primitives,p) siz+=primitives[p].size() + 1;
27268 for (
int c = cimg::
min(primitives._width,colors._width)-1; c>=0; --c) {
27270 else {
const unsigned int csiz = colors[c].size(); siz+=(csiz!=3)?4+csiz:3; }
27272 if (colors._width<primitives._width) siz+=3*(primitives._width - colors._width);
27273 cimglist_for(opacities,o) {
27275 else {
const unsigned int osiz = opacities[o].size(); siz+=(osiz!=1)?4+osiz:1; }
27277 siz+=primitives._width - opacities._width;
27281 template<
typename tp,
typename tc,
typename to>
27282 unsigned int _size_object3dtoCImg3d(
const CImgList<tp>& primitives,
27283 const CImgList<tc>& colors,
27284 const CImg<to>& opacities)
const {
27285 unsigned int siz = 8 + 3*
width();
27286 cimglist_for(primitives,p) siz+=primitives[p].size() + 1;
27287 for (
int c = cimg::
min(primitives._width,colors._width)-1; c>=0; --c) {
27288 const unsigned int csiz = colors[c].size(); siz+=(csiz!=3)?4+csiz:3;
27290 if (colors._width<primitives._width) siz+=3*(primitives._width - colors._width);
27291 siz+=primitives.size();
27297 template<
typename tp,
typename tc>
27305 template<
typename tp>
27315 cimglist_for(primitives,p) primitives(p,0) = p;
27325 template<
typename tp,
typename tc,
typename to>
27331 template<
typename tp,
typename tc,
typename to>
27333 char error_message[1024] = { 0 };
27336 "CImg3dtoobject3d(): image instance is not a CImg3d (%s).",
27337 cimg_instance,error_message);
27338 const T *ptrs = _data + 6;
27340 nb_points = cimg::float2uint((
float)*(ptrs++)),
27341 nb_primitives = cimg::float2uint((
float)*(ptrs++));
27344 primitives.
assign(nb_primitives);
27345 cimglist_for(primitives,p) {
27346 const unsigned int nb_inds = (
unsigned int)*(ptrs++);
27347 primitives[p].
assign(1,nb_inds);
27348 tp *ptrp = primitives[p]._data;
27349 for (
unsigned int i = 0; i<nb_inds; ++i) *(ptrp++) = (tp)cimg::float2uint((
float)*(ptrs++));
27351 colors.
assign(nb_primitives);
27352 cimglist_for(colors,c) {
27353 if (*ptrs==(T)-128) {
27355 const unsigned int w = (
unsigned int)*(ptrs++), h = (
unsigned int)*(ptrs++), s = (
unsigned int)*(ptrs++);
27356 if (!h && !s) colors[c].
assign(colors[w],
true);
27357 else { colors[c].
assign(ptrs,w,h,1,s,
false); ptrs+=w*h*s; }
27358 }
else { colors[c].
assign(ptrs,1,1,1,3,
false); ptrs+=3; }
27360 opacities.
assign(nb_primitives);
27361 cimglist_for(opacities,o) {
27362 if (*ptrs==(T)-128) {
27364 const unsigned int w = (
unsigned int)*(ptrs++), h = (
unsigned int)*(ptrs++), s = (
unsigned int)*(ptrs++);
27365 if (!h && !s) opacities[o].
assign(opacities[w],
true);
27366 else { opacities[o].
assign(ptrs,w,h,1,s,
false); ptrs+=w*h*s; }
27367 }
else opacities[o].
assign(1,1,1,1,*(ptrs++));
27381 template<
typename tc>
27382 CImg<T>& _draw_scanline(
const int x0,
const int x1,
const int y,
27383 const tc *
const color,
const float opacity=1,
27384 const float brightness=1,
const bool init=
false) {
27386 static float nopacity = 0, copacity = 0;
27387 static unsigned long whd = 0;
27388 static const tc *col = 0;
27392 whd = (
unsigned long)_width*_height*_depth;
27394 const int nx0 = x0>0?x0:0, nx1 = x1<
width()?x1:
width()-1, dx = nx1 - nx0;
27397 const unsigned long off = whd - dx - 1;
27398 T *ptrd =
data(nx0,y);
27400 if (brightness==1) {
27401 if (
sizeof(T)!=1) cimg_forC(*
this,c) {
27402 const T val = (T)*(col++);
27403 for (
int x = dx; x>=0; --x) *(ptrd++) = val;
27405 }
else cimg_forC(*
this,c) {
27406 const T val = (T)*(col++);
27407 std::memset(ptrd,(
int)val,dx+1);
27410 }
else if (brightness<1) {
27411 if (
sizeof(T)!=1) cimg_forC(*
this,c) {
27412 const T val = (T)(*(col++)*brightness);
27413 for (
int x = dx; x>=0; --x) *(ptrd++) = val;
27415 }
else cimg_forC(*
this,c) {
27416 const T val = (T)(*(col++)*brightness);
27417 std::memset(ptrd,(
int)val,dx+1);
27421 if (
sizeof(T)!=1) cimg_forC(*
this,c) {
27422 const T val = (T)((2-brightness)**(col++) + (brightness-1)*maxval);
27423 for (
int x = dx; x>=0; --x) *(ptrd++) = val;
27425 }
else cimg_forC(*
this,c) {
27426 const T val = (T)((2-brightness)**(col++) + (brightness-1)*maxval);
27427 std::memset(ptrd,(
int)val,dx+1);
27432 if (brightness==1) {
27433 cimg_forC(*
this,c) {
27434 const T val = (T)*(col++);
27435 for (
int x = dx; x>=0; --x) { *ptrd = (T)(val*nopacity + *ptrd*copacity); ++ptrd; }
27438 }
else if (brightness<=1) {
27439 cimg_forC(*
this,c) {
27440 const T val = (T)(*(col++)*brightness);
27441 for (
int x = dx; x>=0; --x) { *ptrd = (T)(val*nopacity + *ptrd*copacity); ++ptrd; }
27445 cimg_forC(*
this,c) {
27446 const T val = (T)((2-brightness)**(col++) + (brightness-1)*maxval);
27447 for (
int x = dx; x>=0; --x) { *ptrd = (T)(val*nopacity + *ptrd*copacity); ++ptrd; }
27457 template<
typename tc>
27458 CImg<T>& _draw_scanline(
const tc *
const color,
const float opacity=1) {
27459 return _draw_scanline(0,0,0,color,opacity,0,
true);
27478 template<
typename tc>
27480 const tc *
const color,
const float opacity=1) {
27484 "draw_point(): Specified color is (null).",
27487 const unsigned long whd = (
unsigned long)_width*_height*_depth;
27489 T *ptrd =
data(x0,y0,z0,0);
27490 const tc *col = color;
27491 if (opacity>=1) cimg_forC(*
this,c) { *ptrd = (T)*(col++); ptrd+=whd; }
27492 else cimg_forC(*
this,c) { *ptrd = (T)(*(col++)*nopacity + *ptrd*copacity); ptrd+=whd; }
27498 template<
typename tc>
27500 const tc *
const color,
const float opacity=1) {
27510 template<
typename t,
typename tc>
27512 const tc *
const color,
const float opacity=1) {
27513 if (
is_empty() || !points)
return *
this;
27514 switch (points._height) {
27517 "draw_point(): Invalid specified point set (%u,%u,%u,%u,%p).",
27519 points._width,points._height,points._depth,points._spectrum,points._data);
27521 cimg_forX(points,i)
draw_point((
int)points(i,0),(
int)points(i,1),color,opacity);
27524 cimg_forX(points,i)
draw_point((
int)points(i,0),(
int)points(i,1),(
int)points(i,2),color,opacity);
27550 template<
typename tc>
27552 const int x1,
const int y1,
27553 const tc *
const color,
const float opacity=1,
27554 const unsigned int pattern=~0U,
const bool init_hatch=
true) {
27558 "draw_line(): Specified color is (null).",
27560 static unsigned int hatch = ~0U - (~0U>>1);
27561 if (init_hatch) hatch = ~0U - (~0U>>1);
27562 const bool xdir = x0<x1, ydir = y0<y1;
27564 nx0 = x0, nx1 = x1, ny0 = y0, ny1 = y1,
27565 &xleft = xdir?nx0:nx1, &yleft = xdir?ny0:ny1,
27566 &xright = xdir?nx1:nx0, &yright = xdir?ny1:ny0,
27567 &xup = ydir?nx0:nx1, &yup = ydir?ny0:ny1,
27568 &xdown = ydir?nx1:nx0, &ydown = ydir?ny1:ny0;
27569 if (xright<0 || xleft>=
width())
return *
this;
27570 if (xleft<0) { yleft-=(int)((
float)xleft*((float)yright - yleft)/((float)xright - xleft)); xleft = 0; }
27571 if (xright>=
width()) { yright-=(int)(((
float)xright -
width())*((
float)yright - yleft)/((
float)xright - xleft)); xright =
width() - 1; }
27572 if (ydown<0 || yup>=
height())
return *
this;
27573 if (yup<0) { xup-=(int)((
float)yup*((float)xdown - xup)/((float)ydown - yup)); yup = 0; }
27574 if (ydown>=
height()) { xdown-=(int)(((
float)ydown -
height())*((
float)xdown - xup)/((
float)ydown - yup)); ydown =
height() - 1; }
27575 T *ptrd0 =
data(nx0,ny0);
27576 int dx = xright - xleft, dy = ydown - yup;
27577 const bool steep = dy>dx;
27578 if (steep)
cimg::swap(nx0,ny0,nx1,ny1,dx,dy);
27580 offx = (nx0<nx1?1:-1)*(steep?
width():1),
27581 offy = (ny0<ny1?1:-1)*(steep?1:
width());
27582 const unsigned long wh = (
unsigned long)_width*_height;
27584 if (~pattern)
for (
int error = dx>>1, x = 0; x<=dx; ++x) {
27585 if (pattern&hatch) {
27586 T *ptrd = ptrd0;
const tc* col = color;
27587 cimg_forC(*
this,c) { *ptrd = (T)*(col++); ptrd+=wh; }
27589 hatch>>=1;
if (!hatch) hatch = ~0U - (~0U>>1);
27591 if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
27592 }
else for (
int error = dx>>1, x = 0; x<=dx; ++x) {
27593 T *ptrd = ptrd0;
const tc* col = color; cimg_forC(*
this,c) { *ptrd = (T)*(col++); ptrd+=wh; }
27595 if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
27599 if (~pattern)
for (
int error = dx>>1, x = 0; x<=dx; ++x) {
27600 if (pattern&hatch) {
27601 T *ptrd = ptrd0;
const tc* col = color;
27602 cimg_forC(*
this,c) { *ptrd = (T)(nopacity**(col++) + *ptrd*copacity); ptrd+=wh; }
27604 hatch>>=1;
if (!hatch) hatch = ~0U - (~0U>>1);
27606 if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
27607 }
else for (
int error = dx>>1, x = 0; x<=dx; ++x) {
27608 T *ptrd = ptrd0;
const tc* col = color; cimg_forC(*
this,c) { *ptrd = (T)(nopacity**(col++) + *ptrd*copacity); ptrd+=wh; }
27610 if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
27630 template<
typename tz,
typename tc>
27632 const int x0,
const int y0,
const float z0,
27633 const int x1,
const int y1,
const float z1,
27634 const tc *
const color,
const float opacity=1,
27635 const unsigned int pattern=~0U,
const bool init_hatch=
true) {
27636 typedef typename cimg::superset<tz,float>::type tzfloat;
27637 if (
is_empty() || z0<=0 || z1<=0)
return *
this;
27640 "draw_line(): Specified color is (null).",
27644 "draw_line(): Instance and specified Z-buffer (%u,%u,%u,%u,%p) have different dimensions.",
27646 zbuffer._width,zbuffer._height,zbuffer._depth,zbuffer._spectrum,zbuffer._data);
27647 static unsigned int hatch = ~0U - (~0U>>1);
27648 if (init_hatch) hatch = ~0U - (~0U>>1);
27649 const bool xdir = x0<x1, ydir = y0<y1;
27651 nx0 = x0, nx1 = x1, ny0 = y0, ny1 = y1,
27652 &xleft = xdir?nx0:nx1, &yleft = xdir?ny0:ny1,
27653 &xright = xdir?nx1:nx0, &yright = xdir?ny1:ny0,
27654 &xup = ydir?nx0:nx1, &yup = ydir?ny0:ny1,
27655 &xdown = ydir?nx1:nx0, &ydown = ydir?ny1:ny0;
27657 Z0 = 1/(tzfloat)z0, Z1 = 1/(tzfloat)z1, nz0 = Z0, nz1 = Z1, dz = Z1 - Z0,
27658 &zleft = xdir?nz0:nz1,
27659 &zright = xdir?nz1:nz0,
27660 &zup = ydir?nz0:nz1,
27661 &zdown = ydir?nz1:nz0;
27662 if (xright<0 || xleft>=
width())
return *
this;
27664 const float D = (float)xright - xleft;
27665 yleft-=(int)((
float)xleft*((float)yright - yleft)/D);
27666 zleft-=(tzfloat)xleft*(zright - zleft)/D;
27669 if (xright>=
width()) {
27670 const float d = (float)xright -
width(), D = (float)xright - xleft;
27671 yright-=(int)(d*((
float)yright - yleft)/D);
27672 zright-=(tzfloat)d*(zright - zleft)/D;
27673 xright =
width() - 1;
27675 if (ydown<0 || yup>=
height())
return *
this;
27677 const float D = (float)ydown - yup;
27678 xup-=(int)((
float)yup*((float)xdown - xup)/D);
27679 zup-=(tzfloat)yup*(zdown - zup)/D;
27683 const float d = (float)ydown -
height(), D = (float)ydown - yup;
27684 xdown-=(int)(d*((
float)xdown - xup)/D);
27685 zdown-=(tzfloat)d*(zdown - zup)/D;
27688 T *ptrd0 =
data(nx0,ny0);
27689 tz *ptrz = zbuffer.data(nx0,ny0);
27690 int dx = xright - xleft, dy = ydown - yup;
27691 const bool steep = dy>dx;
27692 if (steep)
cimg::swap(nx0,ny0,nx1,ny1,dx,dy);
27694 offx = (nx0<nx1?1:-1)*(steep?
width():1),
27695 offy = (ny0<ny1?1:-1)*(steep?1:
width());
27696 const unsigned long wh = (
unsigned long)_width*_height,
27699 if (~pattern)
for (
int error = dx>>1, x = 0; x<=dx; ++x) {
27700 const tzfloat z = Z0 + x*dz/ndx;
27701 if (z>=(tzfloat)*ptrz && pattern&hatch) {
27703 T *ptrd = ptrd0;
const tc *col = color;
27704 cimg_forC(*
this,c) { *ptrd = (T)*(col++); ptrd+=wh; }
27706 hatch>>=1;
if (!hatch) hatch = ~0U - (~0U>>1);
27707 ptrd0+=offx; ptrz+=offx;
27708 if ((error-=dy)<0) { ptrd0+=offy; ptrz+=offy; error+=dx; }
27709 }
else for (
int error = dx>>1, x = 0; x<=dx; ++x) {
27710 const tzfloat z = Z0 + x*dz/ndx;
27711 if (z>=(tzfloat)*ptrz) {
27713 T *ptrd = ptrd0;
const tc *col = color;
27714 cimg_forC(*
this,c) { *ptrd = (T)*(col++); ptrd+=wh; }
27716 ptrd0+=offx; ptrz+=offx;
27717 if ((error-=dy)<0) { ptrd0+=offy; ptrz+=offy; error+=dx; }
27721 if (~pattern)
for (
int error = dx>>1, x = 0; x<=dx; ++x) {
27722 const tzfloat z = Z0 + x*dz/ndx;
27723 if (z>=(tzfloat)*ptrz && pattern&hatch) {
27725 T *ptrd = ptrd0;
const tc *col = color;
27726 cimg_forC(*
this,c) { *ptrd = (T)(nopacity**(col++) + *ptrd*copacity); ptrd+=wh; }
27728 hatch>>=1;
if (!hatch) hatch = ~0U - (~0U>>1);
27729 ptrd0+=offx; ptrz+=offx;
27730 if ((error-=dy)<0) { ptrd0+=offy; ptrz+=offy; error+=dx; }
27731 }
else for (
int error = dx>>1, x = 0; x<=dx; ++x) {
27732 const tzfloat z = Z0 + x*dz/ndx;
27733 if (z>=(tzfloat)*ptrz) {
27735 T *ptrd = ptrd0;
const tc *col = color;
27736 cimg_forC(*
this,c) { *ptrd = (T)(nopacity**(col++) + *ptrd*copacity); ptrd+=wh; }
27738 ptrd0+=offx; ptrz+=offx;
27739 if ((error-=dy)<0) { ptrd0+=offy; ptrz+=offy; error+=dx; }
27758 template<
typename tc>
27760 const int x1,
const int y1,
const int z1,
27761 const tc *
const color,
const float opacity=1,
27762 const unsigned int pattern=~0U,
const bool init_hatch=
true) {
27766 "draw_line(): Specified color is (null).",
27768 static unsigned int hatch = ~0U - (~0U>>1);
27769 if (init_hatch) hatch = ~0U - (~0U>>1);
27770 int nx0 = x0, ny0 = y0, nz0 = z0, nx1 = x1, ny1 = y1, nz1 = z1;
27771 if (nx0>nx1)
cimg::swap(nx0,nx1,ny0,ny1,nz0,nz1);
27772 if (nx1<0 || nx0>=
width())
return *
this;
27773 if (nx0<0) {
const float D = 1.0f + nx1 - nx0; ny0-=(int)((
float)nx0*(1.0f + ny1 - ny0)/D); nz0-=(int)((
float)nx0*(1.0f + nz1 - nz0)/D); nx0 = 0; }
27774 if (nx1>=
width()) {
const float d = (float)nx1 -
width(), D = 1.0f + nx1 - nx0; ny1+=(int)(d*(1.0f + ny0 - ny1)/D); nz1+=(int)(d*(1.0f + nz0 - nz1)/D); nx1 =
width() - 1; }
27775 if (ny0>ny1)
cimg::swap(nx0,nx1,ny0,ny1,nz0,nz1);
27776 if (ny1<0 || ny0>=
height())
return *
this;
27777 if (ny0<0) {
const float D = 1.0f + ny1 - ny0; nx0-=(int)((
float)ny0*(1.0f + nx1 - nx0)/D); nz0-=(int)((
float)ny0*(1.0f + nz1 - nz0)/D); ny0 = 0; }
27778 if (ny1>=
height()) {
const float d = (float)ny1 -
height(), D = 1.0f + ny1 - ny0; nx1+=(int)(d*(1.0f + nx0 - nx1)/D); nz1+=(int)(d*(1.0f + nz0 - nz1)/D); ny1 =
height() - 1; }
27779 if (nz0>nz1)
cimg::swap(nx0,nx1,ny0,ny1,nz0,nz1);
27780 if (nz1<0 || nz0>=
depth())
return *
this;
27781 if (nz0<0) {
const float D = 1.0f + nz1 - nz0; nx0-=(int)((
float)nz0*(1.0f + nx1 - nx0)/D); ny0-=(int)((
float)nz0*(1.0f + ny1 - ny0)/D); nz0 = 0; }
27782 if (nz1>=
depth()) {
const float d = (float)nz1 -
depth(), D = 1.0f + nz1 - nz0; nx1+=(int)(d*(1.0f + nx0 - nx1)/D); ny1+=(int)(d*(1.0f + ny0 - ny1)/D); nz1 =
depth() - 1; }
27784 const unsigned long whd = (
unsigned long)_width*_height*_depth;
27785 const float px = (nx1 - nx0)/(
float)dmax, py = (ny1 - ny0)/(
float)dmax, pz = (nz1 - nz0)/(
float)dmax;
27786 float x = (float)nx0, y = (
float)ny0, z = (float)nz0;
27787 if (opacity>=1)
for (
unsigned int t = 0; t<=dmax; ++t) {
27788 if (!(~pattern) || (~pattern && pattern&hatch)) {
27789 T* ptrd =
data((
unsigned int)x,(
unsigned int)y,(
unsigned int)z);
27790 const tc *col = color; cimg_forC(*
this,c) { *ptrd = (T)*(col++); ptrd+=whd; }
27792 x+=px; y+=py; z+=pz;
if (pattern) { hatch>>=1;
if (!hatch) hatch = ~0U - (~0U>>1); }
27795 for (
unsigned int t = 0; t<=dmax; ++t) {
27796 if (!(~pattern) || (~pattern && pattern&hatch)) {
27797 T* ptrd =
data((
unsigned int)x,(
unsigned int)y,(
unsigned int)z);
27798 const tc *col = color; cimg_forC(*
this,c) { *ptrd = (T)(*(col++)*nopacity + *ptrd*copacity); ptrd+=whd; }
27800 x+=px; y+=py; z+=pz;
if (pattern) { hatch>>=1;
if (!hatch) hatch = ~0U - (~0U>>1); }
27829 template<
typename tc>
27831 const int x1,
const int y1,
27833 const int tx0,
const int ty0,
27834 const int tx1,
const int ty1,
27835 const float opacity=1,
27836 const unsigned int pattern=~0U,
const bool init_hatch=
true) {
27838 if (texture._depth>1 || texture._spectrum<_spectrum)
27840 "draw_line(): Invalid specified texture (%u,%u,%u,%u,%p).",
27842 texture._width,texture._height,texture._depth,texture._spectrum,texture._data);
27843 if (
is_overlapped(texture))
return draw_line(x0,y0,x1,y1,+texture,tx0,ty0,tx1,ty1,opacity,pattern,init_hatch);
27844 static unsigned int hatch = ~0U - (~0U>>1);
27845 if (init_hatch) hatch = ~0U - (~0U>>1);
27846 const bool xdir = x0<x1, ydir = y0<y1;
27848 dtx = tx1-tx0, dty = ty1-ty0,
27849 nx0 = x0, nx1 = x1, ny0 = y0, ny1 = y1,
27850 tnx0 = tx0, tnx1 = tx1, tny0 = ty0, tny1 = ty1,
27851 &xleft = xdir?nx0:nx1, &yleft = xdir?ny0:ny1, &xright = xdir?nx1:nx0, &yright = xdir?ny1:ny0,
27852 &txleft = xdir?tnx0:tnx1, &tyleft = xdir?tny0:tny1, &txright = xdir?tnx1:tnx0, &tyright = xdir?tny1:tny0,
27853 &xup = ydir?nx0:nx1, &yup = ydir?ny0:ny1, &xdown = ydir?nx1:nx0, &ydown = ydir?ny1:ny0,
27854 &txup = ydir?tnx0:tnx1, &tyup = ydir?tny0:tny1, &txdown = ydir?tnx1:tnx0, &tydown = ydir?tny1:tny0;
27855 if (xright<0 || xleft>=
width())
return *
this;
27857 const float D = (float)xright - xleft;
27858 yleft-=(int)((
float)xleft*((float)yright - yleft)/D);
27859 txleft-=(int)((
float)xleft*((float)txright - txleft)/D);
27860 tyleft-=(int)((
float)xleft*((float)tyright - tyleft)/D);
27863 if (xright>=
width()) {
27864 const float d = (float)xright -
width(), D = (float)xright - xleft;
27865 yright-=(int)(d*((
float)yright - yleft)/D);
27866 txright-=(int)(d*((
float)txright - txleft)/D);
27867 tyright-=(int)(d*((
float)tyright - tyleft)/D);
27868 xright =
width() - 1;
27870 if (ydown<0 || yup>=
height())
return *
this;
27872 const float D = (float)ydown - yup;
27873 xup-=(int)((
float)yup*((float)xdown - xup)/D);
27874 txup-=(int)((
float)yup*((float)txdown - txup)/D);
27875 tyup-=(int)((
float)yup*((float)tydown - tyup)/D);
27879 const float d = (float)ydown -
height(), D = (float)ydown - yup;
27880 xdown-=(int)(d*((
float)xdown - xup)/D);
27881 txdown-=(int)(d*((
float)txdown - txup)/D);
27882 tydown-=(int)(d*((
float)tydown - tyup)/D);
27885 T *ptrd0 =
data(nx0,ny0);
27886 int dx = xright - xleft, dy = ydown - yup;
27887 const bool steep = dy>dx;
27888 if (steep)
cimg::swap(nx0,ny0,nx1,ny1,dx,dy);
27890 offx = (nx0<nx1?1:-1)*(steep?
width():1),
27891 offy = (ny0<ny1?1:-1)*(steep?1:
width()),
27893 const unsigned long wh = (
unsigned long)_width*_height;
27896 if (~pattern)
for (
int error = dx>>1, x = 0; x<=dx; ++x) {
27897 if (pattern&hatch) {
27899 const int tx = tx0 + x*dtx/ndx, ty = ty0 + x*dty/ndx;
27900 cimg_forC(*
this,c) { *ptrd = (T)texture(tx,ty,0,c); ptrd+=wh; }
27902 hatch>>=1;
if (!hatch) hatch = ~0U - (~0U>>1);
27904 if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
27905 }
else for (
int error = dx>>1, x = 0; x<=dx; ++x) {
27907 const int tx = tx0 + x*dtx/ndx, ty = ty0 + x*dty/ndx;
27908 cimg_forC(*
this,c) { *ptrd = (T)texture(tx,ty,0,c); ptrd+=wh; }
27910 if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
27914 if (~pattern)
for (
int error = dx>>1, x = 0; x<=dx; ++x) {
27916 if (pattern&hatch) {
27917 const int tx = tx0 + x*dtx/ndx, ty = ty0 + x*dty/ndx;
27918 cimg_forC(*
this,c) { *ptrd = (T)(nopacity*texture(tx,ty,0,c) + *ptrd*copacity); ptrd+=wh; }
27920 hatch>>=1;
if (!hatch) hatch = ~0U - (~0U>>1);
27922 if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
27923 }
else for (
int error = dx>>1, x = 0; x<=dx; ++x) {
27925 const int tx = tx0 + x*dtx/ndx, ty = ty0 + x*dty/ndx;
27926 cimg_forC(*
this,c) { *ptrd = (T)(nopacity*texture(tx,ty,0,c) + *ptrd*copacity); ptrd+=wh; }
27928 if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
27951 template<
typename tc>
27953 const int x1,
const int y1,
const float z1,
27955 const int tx0,
const int ty0,
27956 const int tx1,
const int ty1,
27957 const float opacity=1,
27958 const unsigned int pattern=~0U,
const bool init_hatch=
true) {
27959 if (
is_empty() && z0<=0 && z1<=0)
return *
this;
27960 if (texture._depth>1 || texture._spectrum<_spectrum)
27962 "draw_line(): Invalid specified texture (%u,%u,%u,%u,%p).",
27964 texture._width,texture._height,texture._depth,texture._spectrum,texture._data);
27965 if (
is_overlapped(texture))
return draw_line(x0,y0,z0,x1,y1,z1,+texture,tx0,ty0,tx1,ty1,opacity,pattern,init_hatch);
27966 static unsigned int hatch = ~0U - (~0U>>1);
27967 if (init_hatch) hatch = ~0U - (~0U>>1);
27968 const bool xdir = x0<x1, ydir = y0<y1;
27970 nx0 = x0, nx1 = x1, ny0 = y0, ny1 = y1,
27971 &xleft = xdir?nx0:nx1, &yleft = xdir?ny0:ny1,
27972 &xright = xdir?nx1:nx0, &yright = xdir?ny1:ny0,
27973 &xup = ydir?nx0:nx1, &yup = ydir?ny0:ny1,
27974 &xdown = ydir?nx1:nx0, &ydown = ydir?ny1:ny0;
27976 Tx0 = tx0/z0, Tx1 = tx1/z1,
27977 Ty0 = ty0/z0, Ty1 = ty1/z1,
27978 Z0 = 1/z0, Z1 = 1/z1,
27979 dz = Z1 - Z0, dtx = Tx1 - Tx0, dty = Ty1 - Ty0,
27980 tnx0 = Tx0, tnx1 = Tx1, tny0 = Ty0, tny1 = Ty1, nz0 = Z0, nz1 = Z1,
27981 &zleft = xdir?nz0:nz1, &txleft = xdir?tnx0:tnx1, &tyleft = xdir?tny0:tny1,
27982 &zright = xdir?nz1:nz0, &txright = xdir?tnx1:tnx0, &tyright = xdir?tny1:tny0,
27983 &zup = ydir?nz0:nz1, &txup = ydir?tnx0:tnx1, &tyup = ydir?tny0:tny1,
27984 &zdown = ydir?nz1:nz0, &txdown = ydir?tnx1:tnx0, &tydown = ydir?tny1:tny0;
27985 if (xright<0 || xleft>=
width())
return *
this;
27987 const float D = (float)xright - xleft;
27988 yleft-=(int)((
float)xleft*((float)yright - yleft)/D);
27989 zleft-=(float)xleft*(zright - zleft)/D;
27990 txleft-=(float)xleft*(txright - txleft)/D;
27991 tyleft-=(float)xleft*(tyright - tyleft)/D;
27994 if (xright>=
width()) {
27995 const float d = (float)xright -
width(), D = (float)xright - xleft;
27996 yright-=(int)(d*((
float)yright - yleft)/D);
27997 zright-=d*(zright - zleft)/D;
27998 txright-=d*(txright - txleft)/D;
27999 tyright-=d*(tyright - tyleft)/D;
28000 xright =
width() - 1;
28002 if (ydown<0 || yup>=
height())
return *
this;
28004 const float D = (float)ydown - yup;
28005 xup-=(int)((
float)yup*((float)xdown - xup)/D);
28006 zup-=(float)yup*(zdown - zup)/D;
28007 txup-=(float)yup*(txdown - txup)/D;
28008 tyup-=(float)yup*(tydown - tyup)/D;
28012 const float d = (float)ydown -
height(), D = (float)ydown - yup;
28013 xdown-=(int)(d*((
float)xdown - xup)/D);
28014 zdown-=d*(zdown - zup)/D;
28015 txdown-=d*(txdown - txup)/D;
28016 tydown-=d*(tydown - tyup)/D;
28019 T *ptrd0 =
data(nx0,ny0);
28020 int dx = xright - xleft, dy = ydown - yup;
28021 const bool steep = dy>dx;
28022 if (steep)
cimg::swap(nx0,ny0,nx1,ny1,dx,dy);
28024 offx = (nx0<nx1?1:-1)*(steep?
width():1),
28025 offy = (ny0<ny1?1:-1)*(steep?1:
width()),
28027 const unsigned long wh = (
unsigned long)_width*_height;
28030 if (~pattern)
for (
int error = dx>>1, x = 0; x<=dx; ++x) {
28031 if (pattern&hatch) {
28032 const float z = Z0 + x*dz/ndx, tx = Tx0 + x*dtx/ndx, ty = Ty0 + x*dty/ndx;
28033 T *ptrd = ptrd0; cimg_forC(*
this,c) { *ptrd = (T)texture((
int)(tx/z),(
int)(ty/z),0,c); ptrd+=wh; }
28035 hatch>>=1;
if (!hatch) hatch = ~0U - (~0U>>1);
28037 if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
28038 }
else for (
int error = dx>>1, x = 0; x<=dx; ++x) {
28039 const float z = Z0 + x*dz/ndx, tx = Tx0 + x*dtx/ndx, ty = Ty0 + x*dty/ndx;
28040 T *ptrd = ptrd0; cimg_forC(*
this,c) { *ptrd = (T)texture((
int)(tx/z),(
int)(ty/z),0,c); ptrd+=wh; }
28042 if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
28046 if (~pattern)
for (
int error = dx>>1, x = 0; x<=dx; ++x) {
28047 if (pattern&hatch) {
28048 const float z = Z0 + x*dz/ndx, tx = Tx0 + x*dtx/ndx, ty = Ty0 + x*dty/ndx;
28049 T *ptrd = ptrd0; cimg_forC(*
this,c) { *ptrd = (T)(nopacity*texture((
int)(tx/z),(
int)(ty/z),0,c) + *ptrd*copacity); ptrd+=wh; }
28051 hatch>>=1;
if (!hatch) hatch = ~0U - (~0U>>1);
28053 if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
28054 }
else for (
int error = dx>>1, x = 0; x<=dx; ++x) {
28055 const float z = Z0 + x*dz/ndx, tx = Tx0 + x*dtx/ndx, ty = Ty0 + x*dty/ndx;
28057 cimg_forC(*
this,c) { *ptrd = (T)(nopacity*texture((
int)(tx/z),(
int)(ty/z),0,c) + *ptrd*copacity); ptrd+=wh; }
28059 if ((error-=dy)<0) { ptrd0+=offy; error+=dx; }
28083 template<
typename tz,
typename tc>
28085 const int x0,
const int y0,
const float z0,
28086 const int x1,
const int y1,
const float z1,
28088 const int tx0,
const int ty0,
28089 const int tx1,
const int ty1,
28090 const float opacity=1,
28091 const unsigned int pattern=~0U,
const bool init_hatch=
true) {
28092 typedef typename cimg::superset<tz,float>::type tzfloat;
28093 if (
is_empty() || z0<=0 || z1<=0)
return *
this;
28096 "draw_line(): Instance and specified Z-buffer (%u,%u,%u,%u,%p) have different dimensions.",
28098 zbuffer._width,zbuffer._height,zbuffer._depth,zbuffer._spectrum,zbuffer._data);
28099 if (texture._depth>1 || texture._spectrum<_spectrum)
28101 "draw_line(): Invalid specified texture (%u,%u,%u,%u,%p).",
28103 texture._width,texture._height,texture._depth,texture._spectrum,texture._data);
28104 if (
is_overlapped(texture))
return draw_line(zbuffer,x0,y0,z0,x1,y1,z1,+texture,tx0,ty0,tx1,ty1,opacity,pattern,init_hatch);
28105 static unsigned int hatch = ~0U - (~0U>>1);
28106 if (init_hatch) hatch = ~0U - (~0U>>1);
28107 const bool xdir = x0<x1, ydir = y0<y1;
28109 nx0 = x0, nx1 = x1, ny0 = y0, ny1 = y1,
28110 &xleft = xdir?nx0:nx1, &yleft = xdir?ny0:ny1,
28111 &xright = xdir?nx1:nx0, &yright = xdir?ny1:ny0,
28112 &xup = ydir?nx0:nx1, &yup = ydir?ny0:ny1,
28113 &xdown = ydir?nx1:nx0, &ydown = ydir?ny1:ny0;
28115 Tx0 = tx0/z0, Tx1 = tx1/z1,
28116 Ty0 = ty0/z0, Ty1 = ty1/z1,
28117 dtx = Tx1 - Tx0, dty = Ty1 - Ty0,
28118 tnx0 = Tx0, tnx1 = Tx1, tny0 = Ty0, tny1 = Ty1,
28119 &txleft = xdir?tnx0:tnx1, &tyleft = xdir?tny0:tny1,
28120 &txright = xdir?tnx1:tnx0, &tyright = xdir?tny1:tny0,
28121 &txup = ydir?tnx0:tnx1, &tyup = ydir?tny0:tny1,
28122 &txdown = ydir?tnx1:tnx0, &tydown = ydir?tny1:tny0;
28124 Z0 = 1/(tzfloat)z0, Z1 = 1/(tzfloat)z1,
28125 dz = Z1 - Z0, nz0 = Z0, nz1 = Z1,
28126 &zleft = xdir?nz0:nz1,
28127 &zright = xdir?nz1:nz0,
28128 &zup = ydir?nz0:nz1,
28129 &zdown = ydir?nz1:nz0;
28130 if (xright<0 || xleft>=
width())
return *
this;
28132 const float D = (float)xright - xleft;
28133 yleft-=(int)((
float)xleft*((float)yright - yleft)/D);
28134 zleft-=(float)xleft*(zright - zleft)/D;
28135 txleft-=(float)xleft*(txright - txleft)/D;
28136 tyleft-=(float)xleft*(tyright - tyleft)/D;
28139 if (xright>=
width()) {
28140 const float d = (float)xright -
width(), D = (float)xright - xleft;
28141 yright-=(int)(d*((
float)yright - yleft)/D);
28142 zright-=d*(zright - zleft)/D;
28143 txright-=d*(txright - txleft)/D;
28144 tyright-=d*(tyright - tyleft)/D;
28145 xright =
width()-1;
28147 if (ydown<0 || yup>=
height())
return *
this;
28149 const float D = (float)ydown - yup;
28150 xup-=(int)((
float)yup*((float)xdown - xup)/D);
28151 zup-=yup*(zdown - zup)/D;
28152 txup-=yup*(txdown - txup)/D;
28153 tyup-=yup*(tydown - tyup)/D;
28157 const float d = (float)ydown -
height(), D = (float)ydown - yup;
28158 xdown-=(int)(d*((
float)xdown - xup)/D);
28159 zdown-=d*(zdown - zup)/D;
28160 txdown-=d*(txdown - txup)/D;
28161 tydown-=d*(tydown - tyup)/D;
28164 T *ptrd0 =
data(nx0,ny0);
28165 tz *ptrz = zbuffer.data(nx0,ny0);
28166 int dx = xright - xleft, dy = ydown - yup;
28167 const bool steep = dy>dx;
28168 if (steep)
cimg::swap(nx0,ny0,nx1,ny1,dx,dy);
28170 offx = (nx0<nx1?1:-1)*(steep?
width():1),
28171 offy = (ny0<ny1?1:-1)*(steep?1:
width()),
28173 const unsigned long wh = (
unsigned long)_width*_height;
28176 if (~pattern)
for (
int error = dx>>1, x = 0; x<=dx; ++x) {
28177 if (pattern&hatch) {
28178 const tzfloat z = Z0 + x*dz/ndx;
28179 if (z>=(tzfloat)*ptrz) {
28181 const float tx = Tx0 + x*dtx/ndx, ty = Ty0 + x*dty/ndx;
28182 T *ptrd = ptrd0; cimg_forC(*
this,c) { *ptrd = (T)texture((
int)(tx/z),(
int)(ty/z),0,c); ptrd+=wh; }
28185 hatch>>=1;
if (!hatch) hatch = ~0U - (~0U>>1);
28186 ptrd0+=offx; ptrz+=offx;
28187 if ((error-=dy)<0) { ptrd0+=offy; ptrz+=offy; error+=dx; }
28188 }
else for (
int error = dx>>1, x = 0; x<=dx; ++x) {
28189 const tzfloat z = Z0 + x*dz/ndx;
28190 if (z>=(tzfloat)*ptrz) {
28192 const float tx = Tx0 + x*dtx/ndx, ty = Ty0 + x*dty/ndx;
28193 T *ptrd = ptrd0; cimg_forC(*
this,c) { *ptrd = (T)texture((
int)(tx/z),(
int)(ty/z),0,c); ptrd+=wh; }
28195 ptrd0+=offx; ptrz+=offx;
28196 if ((error-=dy)<0) { ptrd0+=offy; ptrz+=offy; error+=dx; }
28200 if (~pattern)
for (
int error = dx>>1, x = 0; x<=dx; ++x) {
28201 if (pattern&hatch) {
28202 const tzfloat z = Z0 + x*dz/ndx;
28203 if (z>=(tzfloat)*ptrz) {
28205 const float tx = Tx0 + x*dtx/ndx, ty = Ty0 + x*dty/ndx;
28206 T *ptrd = ptrd0; cimg_forC(*
this,c) { *ptrd = (T)(nopacity*texture((
int)(tx/z),(
int)(ty/z),0,c) + *ptrd*copacity); ptrd+=wh; }
28209 hatch>>=1;
if (!hatch) hatch = ~0U - (~0U>>1);
28210 ptrd0+=offx; ptrz+=offx;
28211 if ((error-=dy)<0) { ptrd0+=offy; ptrz+=offy; error+=dx; }
28212 }
else for (
int error = dx>>1, x = 0; x<=dx; ++x) {
28213 const tzfloat z = Z0 + x*dz/ndx;
28214 if (z>=(tzfloat)*ptrz) {
28216 const float tx = Tx0 + x*dtx/ndx, ty = Ty0 + x*dty/ndx;
28217 T *ptrd = ptrd0; cimg_forC(*
this,c) { *ptrd = (T)(nopacity*texture((
int)(tx/z),(
int)(ty/z),0,c) + *ptrd*copacity); ptrd+=wh; }
28219 ptrd0+=offx; ptrz+=offx;
28220 if ((error-=dy)<0) { ptrd0+=offy; ptrz+=offx; error+=dx; }
28248 template<
typename t,
typename tc>
28250 const tc *
const color,
const float opacity=1,
28251 const unsigned int pattern=~0U,
const bool init_hatch=
true) {
28252 if (
is_empty() || !points || points._width<2)
return *
this;
28253 bool ninit_hatch = init_hatch;
28254 switch (points._height) {
28257 "draw_line(): Invalid specified point set (%u,%u,%u,%u,%p).",
28259 points._width,points._height,points._depth,points._spectrum,points._data);
28262 const int x0 = (int)points(0,0), y0 = (int)points(0,1);
28263 int ox = x0, oy = y0;
28264 for (
unsigned int i = 1; i<points._width; ++i) {
28265 const int x = (int)points(i,0), y = (int)points(i,1);
28266 draw_line(ox,oy,x,y,color,opacity,pattern,ninit_hatch);
28267 ninit_hatch =
false;
28272 const int x0 = (int)points(0,0), y0 = (int)points(0,1), z0 = (int)points(0,2);
28273 int ox = x0, oy = y0, oz = z0;
28274 for (
unsigned int i = 1; i<points._width; ++i) {
28275 const int x = (int)points(i,0), y = (int)points(i,1), z = (int)points(i,2);
28276 draw_line(ox,oy,oz,x,y,z,color,opacity,pattern,ninit_hatch);
28277 ninit_hatch =
false;
28278 ox = x; oy = y; oz = z;
28297 template<
typename tc>
28299 const int x1,
const int y1,
28300 const tc *
const color,
const float opacity=1,
28301 const float angle=30,
const float length=-10,
28302 const unsigned int pattern=~0U) {
28304 const float u = (float)(x0 - x1), v = (float)(y0 - y1), sq = u*u + v*v,
28305 deg = (float)(angle*
cimg::PI/180), ang = (sq>0)?(
float)std::atan2(v,u):0.0f,
28306 l = (length>=0)?length:-length*(
float)std::sqrt(sq)/100;
28309 cl = (float)std::cos(ang - deg), sl = (float)std::sin(ang - deg),
28310 cr = (float)std::cos(ang + deg), sr = (float)std::sin(ang + deg);
28312 xl = x1 + (int)(l*cl), yl = y1 + (int)(l*sl),
28313 xr = x1 + (int)(l*cr), yr = y1 + (int)(l*sr),
28314 xc = x1 + (int)((l+1)*(cl+cr))/2, yc = y1 + (int)((l+1)*(sl+sr))/2;
28315 draw_line(x0,y0,xc,yc,color,opacity,pattern).draw_triangle(x1,y1,xl,yl,xr,yr,color,opacity);
28352 template<
typename tc>
28354 const int x1,
const int y1,
const float u1,
const float v1,
28355 const tc *
const color,
const float opacity=1,
28356 const float precision=0.25,
const unsigned int pattern=~0U,
28357 const bool init_hatch=
true) {
28361 "draw_spline(): Specified color is (null).",
28363 if (x0==x1 && y0==y1)
return draw_point(x0,y0,color,opacity);
28364 bool ninit_hatch = init_hatch;
28366 ax = u0 + u1 + 2*(x0 - x1),
28367 bx = 3*(x1 - x0) - 2*u0 - u1,
28368 ay = v0 + v1 + 2*(y0 - y1),
28369 by = 3*(y1 - y0) - 2*v0 - v1,
28370 _precision = 1/(std::sqrt(
cimg::sqr((
float)x0-x1)+
cimg::sqr((
float)y0-y1))*(precision>0?precision:1));
28371 int ox = x0, oy = y0;
28372 for (
float t = 0; t<1; t+=_precision) {
28373 const float t2 = t*t, t3 = t2*t;
28375 nx = (int)(ax*t3 + bx*t2 + u0*t + x0),
28376 ny = (int)(ay*t3 + by*t2 + v0*t + y0);
28377 draw_line(ox,oy,nx,ny,color,opacity,pattern,ninit_hatch);
28378 ninit_hatch =
false;
28381 return draw_line(ox,oy,x1,y1,color,opacity,pattern,
false);
28389 template<
typename tc>
28390 CImg<T>&
draw_spline(
const int x0,
const int y0,
const int z0,
const float u0,
const float v0,
const float w0,
28391 const int x1,
const int y1,
const int z1,
const float u1,
const float v1,
const float w1,
28392 const tc *
const color,
const float opacity=1,
28393 const float precision=4,
const unsigned int pattern=~0U,
28394 const bool init_hatch=
true) {
28398 "draw_spline(): Specified color is (null).",
28400 if (x0==x1 && y0==y1 && z0==z1)
return draw_point(x0,y0,z0,color,opacity);
28401 bool ninit_hatch = init_hatch;
28403 ax = u0 + u1 + 2*(x0 - x1),
28404 bx = 3*(x1 - x0) - 2*u0 - u1,
28405 ay = v0 + v1 + 2*(y0 - y1),
28406 by = 3*(y1 - y0) - 2*v0 - v1,
28407 az = w0 + w1 + 2*(z0 - z1),
28408 bz = 3*(z1 - z0) - 2*w0 - w1,
28409 _precision = 1/(std::sqrt(
cimg::sqr(x0-x1)+
cimg::sqr(y0-y1))*(precision>0?precision:1));
28410 int ox = x0, oy = y0, oz = z0;
28411 for (
float t = 0; t<1; t+=_precision) {
28412 const float t2 = t*t, t3 = t2*t;
28414 nx = (int)(ax*t3 + bx*t2 + u0*t + x0),
28415 ny = (int)(ay*t3 + by*t2 + v0*t + y0),
28416 nz = (int)(az*t3 + bz*t2 + w0*t + z0);
28417 draw_line(ox,oy,oz,nx,ny,nz,color,opacity,pattern,ninit_hatch);
28418 ninit_hatch =
false;
28419 ox = nx; oy = ny; oz = nz;
28421 return draw_line(ox,oy,oz,x1,y1,z1,color,opacity,pattern,
false);
28444 template<
typename t>
28446 const int x1,
const int y1,
const float u1,
const float v1,
28448 const int tx0,
const int ty0,
const int tx1,
const int ty1,
28449 const float opacity=1,
28450 const float precision=4,
const unsigned int pattern=~0U,
28451 const bool init_hatch=
true) {
28452 if (texture._depth>1 || texture._spectrum<_spectrum)
28454 "draw_spline(): Invalid specified texture (%u,%u,%u,%u,%p).",
28456 texture._width,texture._height,texture._depth,texture._spectrum,texture._data);
28458 if (
is_overlapped(texture))
return draw_spline(x0,y0,u0,v0,x1,y1,u1,v1,+texture,tx0,ty0,tx1,ty1,precision,opacity,pattern,init_hatch);
28459 if (x0==x1 && y0==y1)
return draw_point(x0,y0,texture.get_vector_at(x0,y0),opacity);
28460 bool ninit_hatch = init_hatch;
28462 ax = u0 + u1 + 2*(x0 - x1),
28463 bx = 3*(x1 - x0) - 2*u0 - u1,
28464 ay = v0 + v1 + 2*(y0 - y1),
28465 by = 3*(y1 - y0) - 2*v0 - v1,
28466 _precision = 1/(std::sqrt(
cimg::sqr(x0-x1)+
cimg::sqr(y0-y1))*(precision>0?precision:1));
28467 int ox = x0, oy = y0, otx = tx0, oty = ty0;
28468 for (
float t1 = 0; t1<1; t1+=_precision) {
28469 const float t2 = t1*t1, t3 = t2*t1;
28471 nx = (int)(ax*t3 + bx*t2 + u0*t1 + x0),
28472 ny = (int)(ay*t3 + by*t2 + v0*t1 + y0),
28473 ntx = tx0 + (int)((tx1-tx0)*t1),
28474 nty = ty0 + (
int)((ty1-ty0)*t1);
28475 draw_line(ox,oy,nx,ny,texture,otx,oty,ntx,nty,opacity,pattern,ninit_hatch);
28476 ninit_hatch =
false;
28477 ox = nx; oy = ny; otx = ntx; oty = nty;
28479 return draw_line(ox,oy,x1,y1,texture,otx,oty,tx1,ty1,opacity,pattern,
false);
28493 template<
typename tp,
typename tt,
typename tc>
28495 const tc *
const color,
const float opacity=1,
28496 const bool is_closed_set=
false,
const float precision=4,
28497 const unsigned int pattern=~0U,
const bool init_hatch=
true) {
28498 if (
is_empty() || !points || !tangents || points._width<2 || tangents._width<2)
return *
this;
28499 bool ninit_hatch = init_hatch;
28500 switch (points._height) {
28503 "draw_spline(): Invalid specified point set (%u,%u,%u,%u,%p).",
28505 points._width,points._height,points._depth,points._spectrum,points._data);
28508 const int x0 = (int)points(0,0), y0 = (int)points(0,1);
28509 const float u0 = (float)tangents(0,0), v0 = (float)tangents(0,1);
28510 int ox = x0, oy = y0;
28511 float ou = u0, ov = v0;
28512 for (
unsigned int i = 1; i<points._width; ++i) {
28513 const int x = (int)points(i,0), y = (int)points(i,1);
28514 const float u = (float)tangents(i,0), v = (float)tangents(i,1);
28515 draw_spline(ox,oy,ou,ov,x,y,u,v,color,precision,opacity,pattern,ninit_hatch);
28516 ninit_hatch =
false;
28517 ox = x; oy = y; ou = u; ov = v;
28519 if (is_closed_set)
draw_spline(ox,oy,ou,ov,x0,y0,u0,v0,color,precision,opacity,pattern,
false);
28522 const int x0 = (int)points(0,0), y0 = (int)points(0,1), z0 = (int)points(0,2);
28523 const float u0 = (float)tangents(0,0), v0 = (float)tangents(0,1), w0 = (float)tangents(0,2);
28524 int ox = x0, oy = y0, oz = z0;
28525 float ou = u0, ov = v0, ow = w0;
28526 for (
unsigned int i = 1; i<points._width; ++i) {
28527 const int x = (int)points(i,0), y = (int)points(i,1), z = (int)points(i,2);
28528 const float u = (float)tangents(i,0), v = (float)tangents(i,1), w = (float)tangents(i,2);
28529 draw_spline(ox,oy,oz,ou,ov,ow,x,y,z,u,v,w,color,opacity,pattern,ninit_hatch);
28530 ninit_hatch =
false;
28531 ox = x; oy = y; oz = z; ou = u; ov = v; ow = w;
28533 if (is_closed_set)
draw_spline(ox,oy,oz,ou,ov,ow,x0,y0,z0,u0,v0,w0,color,precision,opacity,pattern,
false);
28543 template<
typename tp,
typename tc>
28545 const tc *
const color,
const float opacity=1,
28546 const bool is_closed_set=
false,
const float precision=4,
28547 const unsigned int pattern=~0U,
const bool init_hatch=
true) {
28548 if (
is_empty() || !points || points._width<2)
return *
this;
28550 switch (points._height) {
28553 "draw_spline(): Invalid specified point set (%u,%u,%u,%u,%p).",
28555 points._width,points._height,points._depth,points._spectrum,points._data);
28557 tangents.assign(points._width,points._height);
28558 cimg_forX(points,p) {
28560 p0 = is_closed_set?(p+points._width-1)%points._width:(p?p-1:0),
28561 p1 = is_closed_set?(p+1)%points._width:(p+1<points._width?p+1:p);
28563 x = (float)points(p,0),
28564 y = (float)points(p,1),
28565 x0 = (float)points(p0,0),
28566 y0 = (float)points(p0,1),
28567 x1 = (float)points(p1,0),
28568 y1 = (float)points(p1,1),
28571 n0 = 1e-8f + (float)std::sqrt(u0*u0 + v0*v0),
28574 n1 = 1e-8f + (float)std::sqrt(u1*u1 + v1*v1),
28577 n = 1e-8f + (float)std::sqrt(u*u + v*v),
28578 fact = 0.5f*(n0 + n1);
28579 tangents(p,0) = (Tfloat)(fact*u/n);
28580 tangents(p,1) = (Tfloat)(fact*v/n);
28584 tangents.assign(points._width,points._height);
28585 cimg_forX(points,p) {
28587 p0 = is_closed_set?(p+points._width-1)%points._width:(p?p-1:0),
28588 p1 = is_closed_set?(p+1)%points._width:(p+1<points._width?p+1:p);
28590 x = (float)points(p,0),
28591 y = (float)points(p,1),
28592 z = (float)points(p,2),
28593 x0 = (float)points(p0,0),
28594 y0 = (float)points(p0,1),
28595 z0 = (float)points(p0,2),
28596 x1 = (float)points(p1,0),
28597 y1 = (float)points(p1,1),
28598 z1 = (float)points(p1,2),
28602 n0 = 1e-8f + (float)std::sqrt(u0*u0 + v0*v0 + w0*w0),
28606 n1 = 1e-8f + (float)std::sqrt(u1*u1 + v1*v1 + w1*w1),
28610 n = 1e-8f + (float)std::sqrt(u*u + v*v + w*w),
28611 fact = 0.5f*(n0 + n1);
28612 tangents(p,0) = (Tfloat)(fact*u/n);
28613 tangents(p,1) = (Tfloat)(fact*v/n);
28614 tangents(p,2) = (Tfloat)(fact*w/n);
28618 return draw_spline(points,tangents,color,opacity,is_closed_set,precision,pattern,init_hatch);
28622 #define _cimg_for_triangle1(img,xl,xr,y,x0,y0,x1,y1,x2,y2) \
28623 for (int y = y0<0?0:y0, \
28624 xr = y0>=0?x0:(x0-y0*(x2-x0)/(y2-y0)), \
28625 xl = y1>=0?(y0>=0?(y0==y1?x1:x0):(x0-y0*(x1-x0)/(y1-y0))):(x1-y1*(x2-x1)/(y2-y1)), \
28629 _dxn = x2>x1?x2-x1:(_sxn=-1,x1-x2), \
28630 _dxr = x2>x0?x2-x0:(_sxr=-1,x0-x2), \
28631 _dxl = x1>x0?x1-x0:(_sxl=-1,x0-x1), \
28635 _counter = (_dxn-=_dyn?_dyn*(_dxn/_dyn):0, \
28636 _dxr-=_dyr?_dyr*(_dxr/_dyr):0, \
28637 _dxl-=_dyl?_dyl*(_dxl/_dyl):0, \
28638 cimg::min((int)(img)._height-y-1,y2-y)), \
28642 _rxn = _dyn?(x2-x1)/_dyn:0, \
28643 _rxr = _dyr?(x2-x0)/_dyr:0, \
28644 _rxl = (y0!=y1 && y1>0)?(_dyl?(x1-x0)/_dyl:0): \
28645 (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxn); \
28646 _counter>=0; --_counter, ++y, \
28647 xr+=_rxr+((_errr-=_dxr)<0?_errr+=_dyr,_sxr:0), \
28648 xl+=(y!=y1)?_rxl+((_errl-=_dxl)<0?(_errl+=_dyl,_sxl):0): \
28649 (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxl=_rxn, x1-xl))
28651 #define _cimg_for_triangle2(img,xl,cl,xr,cr,y,x0,y0,c0,x1,y1,c1,x2,y2,c2) \
28652 for (int y = y0<0?0:y0, \
28653 xr = y0>=0?x0:(x0-y0*(x2-x0)/(y2-y0)), \
28654 cr = y0>=0?c0:(c0-y0*(c2-c0)/(y2-y0)), \
28655 xl = y1>=0?(y0>=0?(y0==y1?x1:x0):(x0-y0*(x1-x0)/(y1-y0))):(x1-y1*(x2-x1)/(y2-y1)), \
28656 cl = y1>=0?(y0>=0?(y0==y1?c1:c0):(c0-y0*(c1-c0)/(y1-y0))):(c1-y1*(c2-c1)/(y2-y1)), \
28660 _dxn = x2>x1?x2-x1:(_sxn=-1,x1-x2), \
28661 _dxr = x2>x0?x2-x0:(_sxr=-1,x0-x2), \
28662 _dxl = x1>x0?x1-x0:(_sxl=-1,x0-x1), \
28663 _dcn = c2>c1?c2-c1:(_scn=-1,c1-c2), \
28664 _dcr = c2>c0?c2-c0:(_scr=-1,c0-c2), \
28665 _dcl = c1>c0?c1-c0:(_scl=-1,c0-c1), \
28669 _counter =(_dxn-=_dyn?_dyn*(_dxn/_dyn):0, \
28670 _dxr-=_dyr?_dyr*(_dxr/_dyr):0, \
28671 _dxl-=_dyl?_dyl*(_dxl/_dyl):0, \
28672 _dcn-=_dyn?_dyn*(_dcn/_dyn):0, \
28673 _dcr-=_dyr?_dyr*(_dcr/_dyr):0, \
28674 _dcl-=_dyl?_dyl*(_dcl/_dyl):0, \
28675 cimg::min((int)(img)._height-y-1,y2-y)), \
28676 _errn = _dyn/2, _errcn = _errn, \
28677 _errr = _dyr/2, _errcr = _errr, \
28678 _errl = _dyl/2, _errcl = _errl, \
28679 _rxn = _dyn?(x2-x1)/_dyn:0, \
28680 _rcn = _dyn?(c2-c1)/_dyn:0, \
28681 _rxr = _dyr?(x2-x0)/_dyr:0, \
28682 _rcr = _dyr?(c2-c0)/_dyr:0, \
28683 _rxl = (y0!=y1 && y1>0)?(_dyl?(x1-x0)/_dyl:0): \
28684 (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxn), \
28685 _rcl = (y0!=y1 && y1>0)?(_dyl?(c1-c0)/_dyl:0): \
28686 (_errcl=_errcn, _dcl=_dcn, _dyl=_dyn, _scl=_scn, _rcn ); \
28687 _counter>=0; --_counter, ++y, \
28688 xr+=_rxr+((_errr-=_dxr)<0?_errr+=_dyr,_sxr:0), \
28689 cr+=_rcr+((_errcr-=_dcr)<0?_errcr+=_dyr,_scr:0), \
28690 xl+=(y!=y1)?(cl+=_rcl+((_errcl-=_dcl)<0?(_errcl+=_dyl,_scl):0), \
28691 _rxl+((_errl-=_dxl)<0?(_errl+=_dyl,_sxl):0)): \
28692 (_errcl=_errcn, _dcl=_dcn, _dyl=_dyn, _scl=_scn, _rcl=_rcn, cl=c1, \
28693 _errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxl=_rxn, x1-xl))
28695 #define _cimg_for_triangle3(img,xl,txl,tyl,xr,txr,tyr,y,x0,y0,tx0,ty0,x1,y1,tx1,ty1,x2,y2,tx2,ty2) \
28696 for (int y = y0<0?0:y0, \
28697 xr = y0>=0?x0:(x0-y0*(x2-x0)/(y2-y0)), \
28698 txr = y0>=0?tx0:(tx0-y0*(tx2-tx0)/(y2-y0)), \
28699 tyr = y0>=0?ty0:(ty0-y0*(ty2-ty0)/(y2-y0)), \
28700 xl = y1>=0?(y0>=0?(y0==y1?x1:x0):(x0-y0*(x1-x0)/(y1-y0))):(x1-y1*(x2-x1)/(y2-y1)), \
28701 txl = y1>=0?(y0>=0?(y0==y1?tx1:tx0):(tx0-y0*(tx1-tx0)/(y1-y0))):(tx1-y1*(tx2-tx1)/(y2-y1)), \
28702 tyl = y1>=0?(y0>=0?(y0==y1?ty1:ty0):(ty0-y0*(ty1-ty0)/(y1-y0))):(ty1-y1*(ty2-ty1)/(y2-y1)), \
28703 _sxn=1, _stxn=1, _styn=1, \
28704 _sxr=1, _stxr=1, _styr=1, \
28705 _sxl=1, _stxl=1, _styl=1, \
28706 _dxn = x2>x1?x2-x1:(_sxn=-1,x1-x2), \
28707 _dxr = x2>x0?x2-x0:(_sxr=-1,x0-x2), \
28708 _dxl = x1>x0?x1-x0:(_sxl=-1,x0-x1), \
28709 _dtxn = tx2>tx1?tx2-tx1:(_stxn=-1,tx1-tx2), \
28710 _dtxr = tx2>tx0?tx2-tx0:(_stxr=-1,tx0-tx2), \
28711 _dtxl = tx1>tx0?tx1-tx0:(_stxl=-1,tx0-tx1), \
28712 _dtyn = ty2>ty1?ty2-ty1:(_styn=-1,ty1-ty2), \
28713 _dtyr = ty2>ty0?ty2-ty0:(_styr=-1,ty0-ty2), \
28714 _dtyl = ty1>ty0?ty1-ty0:(_styl=-1,ty0-ty1), \
28718 _counter =(_dxn-=_dyn?_dyn*(_dxn/_dyn):0, \
28719 _dxr-=_dyr?_dyr*(_dxr/_dyr):0, \
28720 _dxl-=_dyl?_dyl*(_dxl/_dyl):0, \
28721 _dtxn-=_dyn?_dyn*(_dtxn/_dyn):0, \
28722 _dtxr-=_dyr?_dyr*(_dtxr/_dyr):0, \
28723 _dtxl-=_dyl?_dyl*(_dtxl/_dyl):0, \
28724 _dtyn-=_dyn?_dyn*(_dtyn/_dyn):0, \
28725 _dtyr-=_dyr?_dyr*(_dtyr/_dyr):0, \
28726 _dtyl-=_dyl?_dyl*(_dtyl/_dyl):0, \
28727 cimg::min((int)(img)._height-y-1,y2-y)), \
28728 _errn = _dyn/2, _errtxn = _errn, _errtyn = _errn, \
28729 _errr = _dyr/2, _errtxr = _errr, _errtyr = _errr, \
28730 _errl = _dyl/2, _errtxl = _errl, _errtyl = _errl, \
28731 _rxn = _dyn?(x2-x1)/_dyn:0, \
28732 _rtxn = _dyn?(tx2-tx1)/_dyn:0, \
28733 _rtyn = _dyn?(ty2-ty1)/_dyn:0, \
28734 _rxr = _dyr?(x2-x0)/_dyr:0, \
28735 _rtxr = _dyr?(tx2-tx0)/_dyr:0, \
28736 _rtyr = _dyr?(ty2-ty0)/_dyr:0, \
28737 _rxl = (y0!=y1 && y1>0)?(_dyl?(x1-x0)/_dyl:0): \
28738 (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxn), \
28739 _rtxl = (y0!=y1 && y1>0)?(_dyl?(tx1-tx0)/_dyl:0): \
28740 (_errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxn ), \
28741 _rtyl = (y0!=y1 && y1>0)?(_dyl?(ty1-ty0)/_dyl:0): \
28742 (_errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyn ); \
28743 _counter>=0; --_counter, ++y, \
28744 xr+=_rxr+((_errr-=_dxr)<0?_errr+=_dyr,_sxr:0), \
28745 txr+=_rtxr+((_errtxr-=_dtxr)<0?_errtxr+=_dyr,_stxr:0), \
28746 tyr+=_rtyr+((_errtyr-=_dtyr)<0?_errtyr+=_dyr,_styr:0), \
28747 xl+=(y!=y1)?(txl+=_rtxl+((_errtxl-=_dtxl)<0?(_errtxl+=_dyl,_stxl):0), \
28748 tyl+=_rtyl+((_errtyl-=_dtyl)<0?(_errtyl+=_dyl,_styl):0), \
28749 _rxl+((_errl-=_dxl)<0?(_errl+=_dyl,_sxl):0)): \
28750 (_errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxl=_rtxn, txl=tx1, \
28751 _errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyl=_rtyn, tyl=ty1,\
28752 _errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxl=_rxn, x1-xl))
28754 #define _cimg_for_triangle4(img,xl,cl,txl,tyl,xr,cr,txr,tyr,y,x0,y0,c0,tx0,ty0,x1,y1,c1,tx1,ty1,x2,y2,c2,tx2,ty2) \
28755 for (int y = y0<0?0:y0, \
28756 xr = y0>=0?x0:(x0-y0*(x2-x0)/(y2-y0)), \
28757 cr = y0>=0?c0:(c0-y0*(c2-c0)/(y2-y0)), \
28758 txr = y0>=0?tx0:(tx0-y0*(tx2-tx0)/(y2-y0)), \
28759 tyr = y0>=0?ty0:(ty0-y0*(ty2-ty0)/(y2-y0)), \
28760 xl = y1>=0?(y0>=0?(y0==y1?x1:x0):(x0-y0*(x1-x0)/(y1-y0))):(x1-y1*(x2-x1)/(y2-y1)), \
28761 cl = y1>=0?(y0>=0?(y0==y1?c1:c0):(c0-y0*(c1-c0)/(y1-y0))):(c1-y1*(c2-c1)/(y2-y1)), \
28762 txl = y1>=0?(y0>=0?(y0==y1?tx1:tx0):(tx0-y0*(tx1-tx0)/(y1-y0))):(tx1-y1*(tx2-tx1)/(y2-y1)), \
28763 tyl = y1>=0?(y0>=0?(y0==y1?ty1:ty0):(ty0-y0*(ty1-ty0)/(y1-y0))):(ty1-y1*(ty2-ty1)/(y2-y1)), \
28764 _sxn=1, _scn=1, _stxn=1, _styn=1, \
28765 _sxr=1, _scr=1, _stxr=1, _styr=1, \
28766 _sxl=1, _scl=1, _stxl=1, _styl=1, \
28767 _dxn = x2>x1?x2-x1:(_sxn=-1,x1-x2), \
28768 _dxr = x2>x0?x2-x0:(_sxr=-1,x0-x2), \
28769 _dxl = x1>x0?x1-x0:(_sxl=-1,x0-x1), \
28770 _dcn = c2>c1?c2-c1:(_scn=-1,c1-c2), \
28771 _dcr = c2>c0?c2-c0:(_scr=-1,c0-c2), \
28772 _dcl = c1>c0?c1-c0:(_scl=-1,c0-c1), \
28773 _dtxn = tx2>tx1?tx2-tx1:(_stxn=-1,tx1-tx2), \
28774 _dtxr = tx2>tx0?tx2-tx0:(_stxr=-1,tx0-tx2), \
28775 _dtxl = tx1>tx0?tx1-tx0:(_stxl=-1,tx0-tx1), \
28776 _dtyn = ty2>ty1?ty2-ty1:(_styn=-1,ty1-ty2), \
28777 _dtyr = ty2>ty0?ty2-ty0:(_styr=-1,ty0-ty2), \
28778 _dtyl = ty1>ty0?ty1-ty0:(_styl=-1,ty0-ty1), \
28782 _counter =(_dxn-=_dyn?_dyn*(_dxn/_dyn):0, \
28783 _dxr-=_dyr?_dyr*(_dxr/_dyr):0, \
28784 _dxl-=_dyl?_dyl*(_dxl/_dyl):0, \
28785 _dcn-=_dyn?_dyn*(_dcn/_dyn):0, \
28786 _dcr-=_dyr?_dyr*(_dcr/_dyr):0, \
28787 _dcl-=_dyl?_dyl*(_dcl/_dyl):0, \
28788 _dtxn-=_dyn?_dyn*(_dtxn/_dyn):0, \
28789 _dtxr-=_dyr?_dyr*(_dtxr/_dyr):0, \
28790 _dtxl-=_dyl?_dyl*(_dtxl/_dyl):0, \
28791 _dtyn-=_dyn?_dyn*(_dtyn/_dyn):0, \
28792 _dtyr-=_dyr?_dyr*(_dtyr/_dyr):0, \
28793 _dtyl-=_dyl?_dyl*(_dtyl/_dyl):0, \
28794 cimg::min((int)(img)._height-y-1,y2-y)), \
28795 _errn = _dyn/2, _errcn = _errn, _errtxn = _errn, _errtyn = _errn, \
28796 _errr = _dyr/2, _errcr = _errr, _errtxr = _errr, _errtyr = _errr, \
28797 _errl = _dyl/2, _errcl = _errl, _errtxl = _errl, _errtyl = _errl, \
28798 _rxn = _dyn?(x2-x1)/_dyn:0, \
28799 _rcn = _dyn?(c2-c1)/_dyn:0, \
28800 _rtxn = _dyn?(tx2-tx1)/_dyn:0, \
28801 _rtyn = _dyn?(ty2-ty1)/_dyn:0, \
28802 _rxr = _dyr?(x2-x0)/_dyr:0, \
28803 _rcr = _dyr?(c2-c0)/_dyr:0, \
28804 _rtxr = _dyr?(tx2-tx0)/_dyr:0, \
28805 _rtyr = _dyr?(ty2-ty0)/_dyr:0, \
28806 _rxl = (y0!=y1 && y1>0)?(_dyl?(x1-x0)/_dyl:0): \
28807 (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxn), \
28808 _rcl = (y0!=y1 && y1>0)?(_dyl?(c1-c0)/_dyl:0): \
28809 (_errcl=_errcn, _dcl=_dcn, _dyl=_dyn, _scl=_scn, _rcn ), \
28810 _rtxl = (y0!=y1 && y1>0)?(_dyl?(tx1-tx0)/_dyl:0): \
28811 (_errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxn ), \
28812 _rtyl = (y0!=y1 && y1>0)?(_dyl?(ty1-ty0)/_dyl:0): \
28813 (_errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyn ); \
28814 _counter>=0; --_counter, ++y, \
28815 xr+=_rxr+((_errr-=_dxr)<0?_errr+=_dyr,_sxr:0), \
28816 cr+=_rcr+((_errcr-=_dcr)<0?_errcr+=_dyr,_scr:0), \
28817 txr+=_rtxr+((_errtxr-=_dtxr)<0?_errtxr+=_dyr,_stxr:0), \
28818 tyr+=_rtyr+((_errtyr-=_dtyr)<0?_errtyr+=_dyr,_styr:0), \
28819 xl+=(y!=y1)?(cl+=_rcl+((_errcl-=_dcl)<0?(_errcl+=_dyl,_scl):0), \
28820 txl+=_rtxl+((_errtxl-=_dtxl)<0?(_errtxl+=_dyl,_stxl):0), \
28821 tyl+=_rtyl+((_errtyl-=_dtyl)<0?(_errtyl+=_dyl,_styl):0), \
28822 _rxl+((_errl-=_dxl)<0?(_errl+=_dyl,_sxl):0)): \
28823 (_errcl=_errcn, _dcl=_dcn, _dyl=_dyn, _scl=_scn, _rcl=_rcn, cl=c1, \
28824 _errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxl=_rtxn, txl=tx1, \
28825 _errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyl=_rtyn, tyl=ty1, \
28826 _errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxl=_rxn, x1-xl))
28828 #define _cimg_for_triangle5(img,xl,txl,tyl,lxl,lyl,xr,txr,tyr,lxr,lyr,y,x0,y0,tx0,ty0,lx0,ly0,x1,y1,tx1,ty1,lx1,ly1,x2,y2,tx2,ty2,lx2,ly2) \
28829 for (int y = y0<0?0:y0, \
28830 xr = y0>=0?x0:(x0-y0*(x2-x0)/(y2-y0)), \
28831 txr = y0>=0?tx0:(tx0-y0*(tx2-tx0)/(y2-y0)), \
28832 tyr = y0>=0?ty0:(ty0-y0*(ty2-ty0)/(y2-y0)), \
28833 lxr = y0>=0?lx0:(lx0-y0*(lx2-lx0)/(y2-y0)), \
28834 lyr = y0>=0?ly0:(ly0-y0*(ly2-ly0)/(y2-y0)), \
28835 xl = y1>=0?(y0>=0?(y0==y1?x1:x0):(x0-y0*(x1-x0)/(y1-y0))):(x1-y1*(x2-x1)/(y2-y1)), \
28836 txl = y1>=0?(y0>=0?(y0==y1?tx1:tx0):(tx0-y0*(tx1-tx0)/(y1-y0))):(tx1-y1*(tx2-tx1)/(y2-y1)), \
28837 tyl = y1>=0?(y0>=0?(y0==y1?ty1:ty0):(ty0-y0*(ty1-ty0)/(y1-y0))):(ty1-y1*(ty2-ty1)/(y2-y1)), \
28838 lxl = y1>=0?(y0>=0?(y0==y1?lx1:lx0):(lx0-y0*(lx1-lx0)/(y1-y0))):(lx1-y1*(lx2-lx1)/(y2-y1)), \
28839 lyl = y1>=0?(y0>=0?(y0==y1?ly1:ly0):(ly0-y0*(ly1-ly0)/(y1-y0))):(ly1-y1*(ly2-ly1)/(y2-y1)), \
28840 _sxn=1, _stxn=1, _styn=1, _slxn=1, _slyn=1, \
28841 _sxr=1, _stxr=1, _styr=1, _slxr=1, _slyr=1, \
28842 _sxl=1, _stxl=1, _styl=1, _slxl=1, _slyl=1, \
28843 _dxn = x2>x1?x2-x1:(_sxn=-1,x1-x2), _dyn = y2-y1, \
28844 _dxr = x2>x0?x2-x0:(_sxr=-1,x0-x2), _dyr = y2-y0, \
28845 _dxl = x1>x0?x1-x0:(_sxl=-1,x0-x1), _dyl = y1-y0, \
28846 _dtxn = tx2>tx1?tx2-tx1:(_stxn=-1,tx1-tx2), \
28847 _dtxr = tx2>tx0?tx2-tx0:(_stxr=-1,tx0-tx2), \
28848 _dtxl = tx1>tx0?tx1-tx0:(_stxl=-1,tx0-tx1), \
28849 _dtyn = ty2>ty1?ty2-ty1:(_styn=-1,ty1-ty2), \
28850 _dtyr = ty2>ty0?ty2-ty0:(_styr=-1,ty0-ty2), \
28851 _dtyl = ty1>ty0?ty1-ty0:(_styl=-1,ty0-ty1), \
28852 _dlxn = lx2>lx1?lx2-lx1:(_slxn=-1,lx1-lx2), \
28853 _dlxr = lx2>lx0?lx2-lx0:(_slxr=-1,lx0-lx2), \
28854 _dlxl = lx1>lx0?lx1-lx0:(_slxl=-1,lx0-lx1), \
28855 _dlyn = ly2>ly1?ly2-ly1:(_slyn=-1,ly1-ly2), \
28856 _dlyr = ly2>ly0?ly2-ly0:(_slyr=-1,ly0-ly2), \
28857 _dlyl = ly1>ly0?ly1-ly0:(_slyl=-1,ly0-ly1), \
28858 _counter =(_dxn-=_dyn?_dyn*(_dxn/_dyn):0, \
28859 _dxr-=_dyr?_dyr*(_dxr/_dyr):0, \
28860 _dxl-=_dyl?_dyl*(_dxl/_dyl):0, \
28861 _dtxn-=_dyn?_dyn*(_dtxn/_dyn):0, \
28862 _dtxr-=_dyr?_dyr*(_dtxr/_dyr):0, \
28863 _dtxl-=_dyl?_dyl*(_dtxl/_dyl):0, \
28864 _dtyn-=_dyn?_dyn*(_dtyn/_dyn):0, \
28865 _dtyr-=_dyr?_dyr*(_dtyr/_dyr):0, \
28866 _dtyl-=_dyl?_dyl*(_dtyl/_dyl):0, \
28867 _dlxn-=_dyn?_dyn*(_dlxn/_dyn):0, \
28868 _dlxr-=_dyr?_dyr*(_dlxr/_dyr):0, \
28869 _dlxl-=_dyl?_dyl*(_dlxl/_dyl):0, \
28870 _dlyn-=_dyn?_dyn*(_dlyn/_dyn):0, \
28871 _dlyr-=_dyr?_dyr*(_dlyr/_dyr):0, \
28872 _dlyl-=_dyl?_dyl*(_dlyl/_dyl):0, \
28873 cimg::min((int)(img)._height-y-1,y2-y)), \
28874 _errn = _dyn/2, _errtxn = _errn, _errtyn = _errn, _errlxn = _errn, _errlyn = _errn, \
28875 _errr = _dyr/2, _errtxr = _errr, _errtyr = _errr, _errlxr = _errr, _errlyr = _errr, \
28876 _errl = _dyl/2, _errtxl = _errl, _errtyl = _errl, _errlxl = _errl, _errlyl = _errl, \
28877 _rxn = _dyn?(x2-x1)/_dyn:0, \
28878 _rtxn = _dyn?(tx2-tx1)/_dyn:0, \
28879 _rtyn = _dyn?(ty2-ty1)/_dyn:0, \
28880 _rlxn = _dyn?(lx2-lx1)/_dyn:0, \
28881 _rlyn = _dyn?(ly2-ly1)/_dyn:0, \
28882 _rxr = _dyr?(x2-x0)/_dyr:0, \
28883 _rtxr = _dyr?(tx2-tx0)/_dyr:0, \
28884 _rtyr = _dyr?(ty2-ty0)/_dyr:0, \
28885 _rlxr = _dyr?(lx2-lx0)/_dyr:0, \
28886 _rlyr = _dyr?(ly2-ly0)/_dyr:0, \
28887 _rxl = (y0!=y1 && y1>0)?(_dyl?(x1-x0)/_dyl:0): \
28888 (_errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxn), \
28889 _rtxl = (y0!=y1 && y1>0)?(_dyl?(tx1-tx0)/_dyl:0): \
28890 (_errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxn ), \
28891 _rtyl = (y0!=y1 && y1>0)?(_dyl?(ty1-ty0)/_dyl:0): \
28892 (_errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyn ), \
28893 _rlxl = (y0!=y1 && y1>0)?(_dyl?(lx1-lx0)/_dyl:0): \
28894 (_errlxl=_errlxn, _dlxl=_dlxn, _dyl=_dyn, _slxl=_slxn, _rlxn ), \
28895 _rlyl = (y0!=y1 && y1>0)?(_dyl?(ly1-ly0)/_dyl:0): \
28896 (_errlyl=_errlyn, _dlyl=_dlyn, _dyl=_dyn, _slyl=_slyn, _rlyn ); \
28897 _counter>=0; --_counter, ++y, \
28898 xr+=_rxr+((_errr-=_dxr)<0?_errr+=_dyr,_sxr:0), \
28899 txr+=_rtxr+((_errtxr-=_dtxr)<0?_errtxr+=_dyr,_stxr:0), \
28900 tyr+=_rtyr+((_errtyr-=_dtyr)<0?_errtyr+=_dyr,_styr:0), \
28901 lxr+=_rlxr+((_errlxr-=_dlxr)<0?_errlxr+=_dyr,_slxr:0), \
28902 lyr+=_rlyr+((_errlyr-=_dlyr)<0?_errlyr+=_dyr,_slyr:0), \
28903 xl+=(y!=y1)?(txl+=_rtxl+((_errtxl-=_dtxl)<0?(_errtxl+=_dyl,_stxl):0), \
28904 tyl+=_rtyl+((_errtyl-=_dtyl)<0?(_errtyl+=_dyl,_styl):0), \
28905 lxl+=_rlxl+((_errlxl-=_dlxl)<0?(_errlxl+=_dyl,_slxl):0), \
28906 lyl+=_rlyl+((_errlyl-=_dlyl)<0?(_errlyl+=_dyl,_slyl):0), \
28907 _rxl+((_errl-=_dxl)<0?(_errl+=_dyl,_sxl):0)): \
28908 (_errtxl=_errtxn, _dtxl=_dtxn, _dyl=_dyn, _stxl=_stxn, _rtxl=_rtxn, txl=tx1, \
28909 _errtyl=_errtyn, _dtyl=_dtyn, _dyl=_dyn, _styl=_styn, _rtyl=_rtyn, tyl=ty1, \
28910 _errlxl=_errlxn, _dlxl=_dlxn, _dyl=_dyn, _slxl=_slxn, _rlxl=_rlxn, lxl=lx1, \
28911 _errlyl=_errlyn, _dlyl=_dlyn, _dyl=_dyn, _slyl=_slyn, _rlyl=_rlyn, lyl=ly1, \
28912 _errl=_errn, _dxl=_dxn, _dyl=_dyn, _sxl=_sxn, _rxl=_rxn, x1-xl))
28915 template<
typename tc>
28916 CImg<T>& _draw_triangle(
const int x0,
const int y0,
28917 const int x1,
const int y1,
28918 const int x2,
const int y2,
28919 const tc *
const color,
const float opacity,
28920 const float brightness) {
28921 _draw_scanline(color,opacity);
28922 const float nbrightness = brightness<0?0:(brightness>2?2:brightness);
28923 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2;
28927 if (ny0<
height() && ny2>=0) {
28928 if ((nx1 - nx0)*(ny2 - ny0) - (nx2 - nx0)*(ny1 - ny0)<0)
28929 _cimg_for_triangle1(*
this,xl,xr,y,nx0,ny0,nx1,ny1,nx2,ny2) _draw_scanline(xl,xr,y,color,opacity,nbrightness);
28931 _cimg_for_triangle1(*this,xl,xr,y,nx0,ny0,nx1,ny1,nx2,ny2) _draw_scanline(xr,xl,y,color,opacity,nbrightness);
28947 template<typename tc>
28949 const
int x1, const
int y1,
28950 const
int x2, const
int y2,
28951 const tc *const color, const
float opacity=1) {
28955 "draw_triangle(): Specified color is (null).",
28957 _draw_triangle(x0,y0,x1,y1,x2,y2,color,opacity,1);
28973 template<
typename tc>
28975 const int x1,
const int y1,
28976 const int x2,
const int y2,
28977 const tc *
const color,
const float opacity,
28978 const unsigned int pattern) {
28982 "draw_triangle(): Specified color is (null).",
28984 draw_line(x0,y0,x1,y1,color,opacity,pattern,
true).
28985 draw_line(x1,y1,x2,y2,color,opacity,pattern,
false).
28986 draw_line(x2,y2,x0,y0,color,opacity,pattern,
false);
29006 template<
typename tz,
typename tc>
29008 const int x0,
const int y0,
const float z0,
29009 const int x1,
const int y1,
const float z1,
29010 const int x2,
const int y2,
const float z2,
29011 const tc *
const color,
const float opacity=1,
29012 const float brightness=1) {
29013 typedef typename cimg::superset<tz,float>::type tzfloat;
29014 if (
is_empty() || z0<=0 || z1<=0 || z2<=0)
return *
this;
29017 "draw_triangle(): Specified color is (null).",
29021 "draw_triangle(): Instance and specified Z-buffer (%u,%u,%u,%u,%p) have different dimensions.",
29023 zbuffer._width,zbuffer._height,zbuffer._depth,zbuffer._spectrum,zbuffer._data);
29027 nbrightness = brightness<0?0:(brightness>2?2:brightness);
29028 const long whd = (long)_width*_height*_depth, offx = _spectrum*whd;
29029 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2;
29030 tzfloat nz0 = 1/(tzfloat)z0, nz1 = 1/(tzfloat)z1, nz2 = 1/(tzfloat)z2;
29031 if (ny0>ny1)
cimg::swap(nx0,nx1,ny0,ny1,nz0,nz1);
29032 if (ny0>ny2)
cimg::swap(nx0,nx2,ny0,ny2,nz0,nz2);
29033 if (ny1>ny2)
cimg::swap(nx1,nx2,ny1,ny2,nz1,nz2);
29034 if (ny0>=
height() || ny2<0)
return *
this;
29036 pzl = (nz1 - nz0)/(ny1 - ny0),
29037 pzr = (nz2 - nz0)/(ny2 - ny0),
29038 pzn = (nz2 - nz1)/(ny2 - ny1),
29039 zr = ny0>=0?nz0:(nz0 - ny0*(nz2 - nz0)/(ny2 - ny0)),
29040 zl = ny1>=0?(ny0>=0?nz0:(nz0 - ny0*(nz1 - nz0)/(ny1 - ny0))):(pzl=pzn,(nz1 - ny1*(nz2 - nz1)/(ny2 - ny1)));
29041 _cimg_for_triangle1(*
this,xleft0,xright0,y,nx0,ny0,nx1,ny1,nx2,ny2) {
29042 if (y==ny1) { zl = nz1; pzl = pzn; }
29043 int xleft = xleft0, xright = xright0;
29044 tzfloat zleft = zl, zright = zr;
29045 if (xright<xleft)
cimg::swap(xleft,xright,zleft,zright);
29046 const int dx = xright - xleft;
29047 const tzfloat pentez = (zright - zleft)/dx;
29048 if (xleft<0 && dx) zleft-=xleft*(zright - zleft)/dx;
29049 if (xleft<0) xleft = 0;
29050 if (xright>=
width()-1) xright =
width() - 1;
29051 T* ptrd =
data(xleft,y,0,0);
29052 tz *ptrz = zbuffer.data(xleft,y);
29054 if (nbrightness==1)
for (
int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) {
29055 if (zleft>=(tzfloat)*ptrz) {
29057 const tc *col = color; cimg_forC(*
this,c) { *ptrd = (T)*(col++); ptrd+=whd; }
29061 }
else if (nbrightness<1)
for (
int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) {
29062 if (zleft>=(tzfloat)*ptrz) {
29064 const tc *col = color; cimg_forC(*
this,c) { *ptrd = (T)(nbrightness*(*col++)); ptrd+=whd; }
29068 }
else for (
int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) {
29069 if (zleft>=(tzfloat)*ptrz) {
29071 const tc *col = color; cimg_forC(*
this,c) { *ptrd = (T)((2-nbrightness)**(col++) + (nbrightness-1)*maxval); ptrd+=whd; }
29077 if (nbrightness==1)
for (
int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) {
29078 if (zleft>=(tzfloat)*ptrz) {
29080 const tc *col = color; cimg_forC(*
this,c) { *ptrd = (T)(nopacity**(col++) + *ptrd*copacity); ptrd+=whd; }
29084 }
else if (nbrightness<1)
for (
int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) {
29085 if (zleft>=(tzfloat)*ptrz) {
29087 const tc *col = color; cimg_forC(*
this,c) { *ptrd = (T)(nopacity*nbrightness**(col++) + *ptrd*copacity); ptrd+=whd; }
29091 }
else for (
int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) {
29092 if (zleft>=(tzfloat)*ptrz) {
29094 const tc *col = color;
29095 cimg_forC(*
this,c) {
29096 const T val = (T)((2-nbrightness)**(col++) + (nbrightness-1)*maxval);
29097 *ptrd = (T)(nopacity*val + *ptrd*copacity);
29124 template<
typename tc>
29126 const int x1,
const int y1,
29127 const int x2,
const int y2,
29128 const tc *
const color,
29129 const float brightness0,
29130 const float brightness1,
29131 const float brightness2,
29132 const float opacity=1) {
29136 "draw_triangle(): Specified color is (null).",
29140 const long whd = (long)_width*_height*_depth, offx = _spectrum*whd-1;
29141 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2,
29142 nc0 = (int)((brightness0<0.0f?0.0f:(brightness0>2.0f?2.0f:brightness0))*256.0f),
29143 nc1 = (int)((brightness1<0.0f?0.0f:(brightness1>2.0f?2.0f:brightness1))*256.0f),
29144 nc2 = (int)((brightness2<0.0f?0.0f:(brightness2>2.0f?2.0f:brightness2))*256.0f);
29145 if (ny0>ny1)
cimg::swap(nx0,nx1,ny0,ny1,nc0,nc1);
29146 if (ny0>ny2)
cimg::swap(nx0,nx2,ny0,ny2,nc0,nc2);
29147 if (ny1>ny2)
cimg::swap(nx1,nx2,ny1,ny2,nc1,nc2);
29148 if (ny0>=
height() || ny2<0)
return *
this;
29149 _cimg_for_triangle2(*
this,xleft0,cleft0,xright0,cright0,y,nx0,ny0,nc0,nx1,ny1,nc1,nx2,ny2,nc2) {
29150 int xleft = xleft0, xright = xright0, cleft = cleft0, cright = cright0;
29151 if (xright<xleft)
cimg::swap(xleft,xright,cleft,cright);
29153 dx = xright - xleft,
29154 dc = cright>cleft?cright - cleft:cleft - cright,
29155 rc = dx?(cright - cleft)/dx:0,
29156 sc = cright>cleft?1:-1,
29157 ndc = dc-(dx?dx*(dc/dx):0);
29159 if (xleft<0 && dx) cleft-=xleft*(cright - cleft)/dx;
29160 if (xleft<0) xleft = 0;
29161 if (xright>=
width()-1) xright =
width() - 1;
29162 T* ptrd =
data(xleft,y);
29163 if (opacity>=1)
for (
int x = xleft; x<=xright; ++x) {
29164 const tc *col = color;
29165 cimg_forC(*
this,c) {
29166 *ptrd = (T)(cleft<256?cleft**(col++)/256:((512-cleft)**(col++)+(cleft-256)*maxval)/256);
29170 cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0);
29171 }
else for (
int x = xleft; x<=xright; ++x) {
29172 const tc *col = color;
29173 cimg_forC(*
this,c) {
29174 const T val = (T)(cleft<256?cleft**(col++)/256:((512-cleft)**(col++)+(cleft-256)*maxval)/256);
29175 *ptrd = (T)(nopacity*val + *ptrd*copacity);
29179 cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0);
29186 template<
typename tz,
typename tc>
29188 const int x0,
const int y0,
const float z0,
29189 const int x1,
const int y1,
const float z1,
29190 const int x2,
const int y2,
const float z2,
29191 const tc *
const color,
29192 const float brightness0,
29193 const float brightness1,
29194 const float brightness2,
29195 const float opacity=1) {
29196 typedef typename cimg::superset<tz,float>::type tzfloat;
29197 if (
is_empty() || z0<=0 || z1<=0 || z2<=0)
return *
this;
29200 "draw_triangle(): Specified color is (null).",
29204 "draw_triangle(): Instance and specified Z-buffer (%u,%u,%u,%u,%p) have different dimensions.",
29206 zbuffer._width,zbuffer._height,zbuffer._depth,zbuffer._spectrum,zbuffer._data);
29209 const long whd = (long)_width*_height*_depth, offx = _spectrum*whd;
29210 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2,
29211 nc0 = (int)((brightness0<0.0f?0.0f:(brightness0>2.0f?2.0f:brightness0))*256.0f),
29212 nc1 = (int)((brightness1<0.0f?0.0f:(brightness1>2.0f?2.0f:brightness1))*256.0f),
29213 nc2 = (int)((brightness2<0.0f?0.0f:(brightness2>2.0f?2.0f:brightness2))*256.0f);
29214 tzfloat nz0 = 1/(tzfloat)z0, nz1 = 1/(tzfloat)z1, nz2 = 1/(tzfloat)z2;
29215 if (ny0>ny1)
cimg::swap(nx0,nx1,ny0,ny1,nz0,nz1,nc0,nc1);
29216 if (ny0>ny2)
cimg::swap(nx0,nx2,ny0,ny2,nz0,nz2,nc0,nc2);
29217 if (ny1>ny2)
cimg::swap(nx1,nx2,ny1,ny2,nz1,nz2,nc1,nc2);
29218 if (ny0>=
height() || ny2<0)
return *
this;
29220 pzl = (nz1 - nz0)/(ny1 - ny0),
29221 pzr = (nz2 - nz0)/(ny2 - ny0),
29222 pzn = (nz2 - nz1)/(ny2 - ny1),
29223 zr = ny0>=0?nz0:(nz0 - ny0*(nz2 - nz0)/(ny2 - ny0)),
29224 zl = ny1>=0?(ny0>=0?nz0:(nz0 - ny0*(nz1 - nz0)/(ny1 - ny0))):(pzl=pzn,(nz1 - ny1*(nz2 - nz1)/(ny2 - ny1)));
29225 _cimg_for_triangle2(*
this,xleft0,cleft0,xright0,cright0,y,nx0,ny0,nc0,nx1,ny1,nc1,nx2,ny2,nc2) {
29226 if (y==ny1) { zl = nz1; pzl = pzn; }
29227 int xleft = xleft0, xright = xright0, cleft = cleft0, cright = cright0;
29228 tzfloat zleft = zl, zright = zr;
29229 if (xright<xleft)
cimg::swap(xleft,xright,zleft,zright,cleft,cright);
29231 dx = xright - xleft,
29232 dc = cright>cleft?cright - cleft:cleft - cright,
29233 rc = dx?(cright-cleft)/dx:0,
29234 sc = cright>cleft?1:-1,
29235 ndc = dc-(dx?dx*(dc/dx):0);
29236 const tzfloat pentez = (zright - zleft)/dx;
29238 if (xleft<0 && dx) {
29239 cleft-=xleft*(cright - cleft)/dx;
29240 zleft-=xleft*(zright - zleft)/dx;
29242 if (xleft<0) xleft = 0;
29244 T *ptrd =
data(xleft,y);
29245 tz *ptrz = zbuffer.data(xleft,y);
29246 if (opacity>=1)
for (
int x = xleft; x<=xright; ++x, ++ptrd, ++ptrz) {
29247 if (zleft>=(tzfloat)*ptrz) {
29249 const tc *col = color;
29250 cimg_forC(*
this,c) {
29251 *ptrd = (T)(cleft<256?cleft**(col++)/256:((512-cleft)**(col++)+(cleft-256)*maxval)/256);
29257 cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0);
29258 }
else for (
int x = xleft; x<=xright; ++x, ++ptrd, ++ptrz) {
29259 if (zleft>=(tzfloat)*ptrz) {
29261 const tc *col = color;
29262 cimg_forC(*
this,c) {
29263 const T val = (T)(cleft<256?cleft**(col++)/256:((512-cleft)**(col++)+(cleft-256)*maxval)/256);
29264 *ptrd = (T)(nopacity*val + *ptrd*copacity);
29270 cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0);
29290 template<
typename tc1,
typename tc2,
typename tc3>
29292 const int x1,
const int y1,
29293 const int x2,
const int y2,
29294 const tc1 *
const color1,
29295 const tc2 *
const color2,
29296 const tc3 *
const color3,
29297 const float opacity=1) {
29298 const unsigned char one = 1;
29299 cimg_forC(*
this,c)
get_shared_channel(c).draw_triangle(x0,y0,x1,y1,x2,y2,&one,color1[c],color2[c],color3[c],opacity);
29321 template<
typename tc>
29323 const int x1,
const int y1,
29324 const int x2,
const int y2,
29326 const int tx0,
const int ty0,
29327 const int tx1,
const int ty1,
29328 const int tx2,
const int ty2,
29329 const float opacity=1,
29330 const float brightness=1) {
29332 if (texture._depth>1 || texture._spectrum<_spectrum)
29334 "draw_triangle(): Invalid specified texture (%u,%u,%u,%u,%p).",
29336 texture._width,texture._height,texture._depth,texture._spectrum,texture._data);
29337 if (
is_overlapped(texture))
return draw_triangle(x0,y0,x1,y1,x2,y2,+texture,tx0,ty0,tx1,ty1,tx2,ty2,opacity,brightness);
29341 nbrightness = brightness<0?0:(brightness>2?2:brightness);
29342 const long whd = (long)_width*_height*_depth, twhd = (
long)texture._width*texture._height*texture._depth, offx = _spectrum*whd-1;
29343 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2,
29344 ntx0 = tx0, nty0 = ty0, ntx1 = tx1, nty1 = ty1, ntx2 = tx2, nty2 = ty2;
29345 if (ny0>ny1)
cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1);
29346 if (ny0>ny2)
cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2);
29347 if (ny1>ny2)
cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2);
29348 if (ny0>=
height() || ny2<0)
return *
this;
29349 _cimg_for_triangle3(*
this,xleft0,txleft0,tyleft0,xright0,txright0,tyright0,y,
29350 nx0,ny0,ntx0,nty0,nx1,ny1,ntx1,nty1,nx2,ny2,ntx2,nty2) {
29352 xleft = xleft0, xright = xright0,
29353 txleft = txleft0, txright = txright0,
29354 tyleft = tyleft0, tyright = tyright0;
29355 if (xright<xleft)
cimg::swap(xleft,xright,txleft,txright,tyleft,tyright);
29357 dx = xright - xleft,
29358 dtx = txright>txleft?txright - txleft:txleft - txright,
29359 dty = tyright>tyleft?tyright - tyleft:tyleft - tyright,
29360 rtx = dx?(txright - txleft)/dx:0,
29361 rty = dx?(tyright - tyleft)/dx:0,
29362 stx = txright>txleft?1:-1,
29363 sty = tyright>tyleft?1:-1,
29364 ndtx = dtx - (dx?dx*(dtx/dx):0),
29365 ndty = dty - (dx?dx*(dty/dx):0);
29366 int errtx = dx>>1, errty = errtx;
29367 if (xleft<0 && dx) {
29368 txleft-=xleft*(txright - txleft)/dx;
29369 tyleft-=xleft*(tyright - tyleft)/dx;
29371 if (xleft<0) xleft = 0;
29373 T* ptrd =
data(xleft,y,0,0);
29375 if (nbrightness==1)
for (
int x = xleft; x<=xright; ++x) {
29376 const tc *col = texture.data(txleft,tyleft);
29377 cimg_forC(*
this,c) {
29379 ptrd+=whd; col+=twhd;
29382 txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0);
29383 tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0);
29384 }
else if (nbrightness<1)
for (
int x = xleft; x<=xright; ++x) {
29385 const tc *col = texture.data(txleft,tyleft);
29386 cimg_forC(*
this,c) {
29387 *ptrd = (T)(nbrightness**col);
29388 ptrd+=whd; col+=twhd;
29391 txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0);
29392 tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0);
29393 }
else for (
int x = xleft; x<=xright; ++x) {
29394 const tc *col = texture.data(txleft,tyleft);
29395 cimg_forC(*
this,c) {
29396 *ptrd = (T)((2-nbrightness)**(col++) + (nbrightness-1)*maxval);
29397 ptrd+=whd; col+=twhd;
29400 txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0);
29401 tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0);
29404 if (nbrightness==1)
for (
int x = xleft; x<=xright; ++x) {
29405 const tc *col = texture.data(txleft,tyleft);
29406 cimg_forC(*
this,c) {
29407 *ptrd = (T)(nopacity**col + *ptrd*copacity);
29408 ptrd+=whd; col+=twhd;
29411 txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0);
29412 tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0);
29413 }
else if (nbrightness<1)
for (
int x = xleft; x<=xright; ++x) {
29414 const tc *col = texture.data(txleft,tyleft);
29415 cimg_forC(*
this,c) {
29416 *ptrd = (T)(nopacity*nbrightness**col + *ptrd*copacity);
29417 ptrd+=whd; col+=twhd;
29420 txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0);
29421 tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0);
29422 }
else for (
int x = xleft; x<=xright; ++x) {
29423 const tc *col = texture.data(txleft,tyleft);
29424 cimg_forC(*
this,c) {
29425 const T val = (T)((2-nbrightness)**(col++) + (nbrightness-1)*maxval);
29426 *ptrd = (T)(nopacity*val + *ptrd*copacity);
29427 ptrd+=whd; col+=twhd;
29430 txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0);
29431 tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0);
29439 template<
typename tc>
29441 const int x1,
const int y1,
const float z1,
29442 const int x2,
const int y2,
const float z2,
29444 const int tx0,
const int ty0,
29445 const int tx1,
const int ty1,
29446 const int tx2,
const int ty2,
29447 const float opacity=1,
29448 const float brightness=1) {
29449 if (
is_empty() || z0<=0 || z1<=0 || z2<=0)
return *
this;
29450 if (texture._depth>1 || texture._spectrum<_spectrum)
29452 "draw_triangle(): Invalid specified texture (%u,%u,%u,%u,%p).",
29454 texture._width,texture._height,texture._depth,texture._spectrum,texture._data);
29455 if (
is_overlapped(texture))
return draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,+texture,tx0,ty0,tx1,ty1,tx2,ty2,opacity,brightness);
29459 nbrightness = brightness<0?0:(brightness>2?2:brightness);
29460 const long whd = (long)_width*_height*_depth, twhd = (
long)texture._width*texture._height*texture._depth, offx = _spectrum*whd-1;
29461 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2;
29463 ntx0 = tx0/z0, nty0 = ty0/z0,
29464 ntx1 = tx1/z1, nty1 = ty1/z1,
29465 ntx2 = tx2/z2, nty2 = ty2/z2,
29466 nz0 = 1/z0, nz1 = 1/z1, nz2 = 1/z2;
29467 if (ny0>ny1)
cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nz0,nz1);
29468 if (ny0>ny2)
cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nz0,nz2);
29469 if (ny1>ny2)
cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nz1,nz2);
29470 if (ny0>=
height() || ny2<0)
return *
this;
29472 ptxl = (ntx1 - ntx0)/(ny1 - ny0),
29473 ptxr = (ntx2 - ntx0)/(ny2 - ny0),
29474 ptxn = (ntx2 - ntx1)/(ny2 - ny1),
29475 ptyl = (nty1 - nty0)/(ny1 - ny0),
29476 ptyr = (nty2 - nty0)/(ny2 - ny0),
29477 ptyn = (nty2 - nty1)/(ny2 - ny1),
29478 pzl = (nz1 - nz0)/(ny1 - ny0),
29479 pzr = (nz2 - nz0)/(ny2 - ny0),
29480 pzn = (nz2 - nz1)/(ny2 - ny1),
29481 zr = ny0>=0?nz0:(nz0 - ny0*(nz2 - nz0)/(ny2 - ny0)),
29482 txr = ny0>=0?ntx0:(ntx0 - ny0*(ntx2 - ntx0)/(ny2 - ny0)),
29483 tyr = ny0>=0?nty0:(nty0 - ny0*(nty2 - nty0)/(ny2 - ny0)),
29484 zl = ny1>=0?(ny0>=0?nz0:(nz0 - ny0*(nz1 - nz0)/(ny1 - ny0))):(pzl=pzn,(nz1 - ny1*(nz2 - nz1)/(ny2 - ny1))),
29485 txl = ny1>=0?(ny0>=0?ntx0:(ntx0 - ny0*(ntx1 - ntx0)/(ny1 - ny0))):(ptxl=ptxn,(ntx1 - ny1*(ntx2 - ntx1)/(ny2 - ny1))),
29486 tyl = ny1>=0?(ny0>=0?nty0:(nty0 - ny0*(nty1 - nty0)/(ny1 - ny0))):(ptyl=ptyn,(nty1 - ny1*(nty2 - nty1)/(ny2 - ny1)));
29487 _cimg_for_triangle1(*
this,xleft0,xright0,y,nx0,ny0,nx1,ny1,nx2,ny2) {
29488 if (y==ny1) { zl = nz1; txl = ntx1; tyl = nty1; pzl = pzn; ptxl = ptxn; ptyl = ptyn; }
29489 int xleft = xleft0, xright = xright0;
29491 zleft = zl, zright = zr,
29492 txleft = txl, txright = txr,
29493 tyleft = tyl, tyright = tyr;
29494 if (xright<xleft)
cimg::swap(xleft,xright,zleft,zright,txleft,txright,tyleft,tyright);
29495 const int dx = xright - xleft;
29497 pentez = (zright - zleft)/dx,
29498 pentetx = (txright - txleft)/dx,
29499 pentety = (tyright - tyleft)/dx;
29500 if (xleft<0 && dx) {
29501 zleft-=xleft*(zright - zleft)/dx;
29502 txleft-=xleft*(txright - txleft)/dx;
29503 tyleft-=xleft*(tyright - tyleft)/dx;
29505 if (xleft<0) xleft = 0;
29507 T* ptrd =
data(xleft,y,0,0);
29509 if (nbrightness==1)
for (
int x = xleft; x<=xright; ++x) {
29510 const float invz = 1/zleft;
29511 const tc *col = texture.data((
int)(txleft*invz),(
int)(tyleft*invz));
29512 cimg_forC(*
this,c) {
29514 ptrd+=whd; col+=twhd;
29516 ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
29517 }
else if (nbrightness<1)
for (
int x=xleft; x<=xright; ++x) {
29518 const float invz = 1/zleft;
29519 const tc *col = texture.data((
int)(txleft*invz),(
int)(tyleft*invz));
29520 cimg_forC(*
this,c) {
29521 *ptrd = (T)(nbrightness**col);
29522 ptrd+=whd; col+=twhd;
29524 ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
29525 }
else for (
int x = xleft; x<=xright; ++x) {
29526 const float invz = 1/zleft;
29527 const tc *col = texture.data((
int)(txleft*invz),(
int)(tyleft*invz));
29528 cimg_forC(*
this,c) {
29529 *ptrd = (T)((2-nbrightness)**col + (nbrightness-1)*maxval);
29530 ptrd+=whd; col+=twhd;
29532 ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
29535 if (nbrightness==1)
for (
int x = xleft; x<=xright; ++x) {
29536 const float invz = 1/zleft;
29537 const tc *col = texture.data((
int)(txleft*invz),(
int)(tyleft*invz));
29538 cimg_forC(*
this,c) {
29539 *ptrd = (T)(nopacity**col + *ptrd*copacity);
29540 ptrd+=whd; col+=twhd;
29542 ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
29543 }
else if (nbrightness<1)
for (
int x = xleft; x<=xright; ++x) {
29544 const float invz = 1/zleft;
29545 const tc *col = texture.data((
int)(txleft*invz),(
int)(tyleft*invz));
29546 cimg_forC(*
this,c) {
29547 *ptrd = (T)(nopacity*nbrightness**col + *ptrd*copacity);
29548 ptrd+=whd; col+=twhd;
29550 ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
29551 }
else for (
int x = xleft; x<=xright; ++x) {
29552 const float invz = 1/zleft;
29553 const tc *col = texture.data((
int)(txleft*invz),(
int)(tyleft*invz));
29554 cimg_forC(*
this,c) {
29555 const T val = (T)((2-nbrightness)**col + (nbrightness-1)*maxval);
29556 *ptrd = (T)(nopacity*val + *ptrd*copacity);
29557 ptrd+=whd; col+=twhd;
29559 ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
29562 zr+=pzr; txr+=ptxr; tyr+=ptyr; zl+=pzl; txl+=ptxl; tyl+=ptyl;
29568 template<
typename tz,
typename tc>
29570 const int x0,
const int y0,
const float z0,
29571 const int x1,
const int y1,
const float z1,
29572 const int x2,
const int y2,
const float z2,
29574 const int tx0,
const int ty0,
29575 const int tx1,
const int ty1,
29576 const int tx2,
const int ty2,
29577 const float opacity=1,
29578 const float brightness=1) {
29579 typedef typename cimg::superset<tz,float>::type tzfloat;
29580 if (
is_empty() || z0<=0 || z1<=0 || z2<=0)
return *
this;
29583 "draw_triangle(): Instance and specified Z-buffer (%u,%u,%u,%u,%p) have different dimensions.",
29585 zbuffer._width,zbuffer._height,zbuffer._depth,zbuffer._spectrum,zbuffer._data);
29587 if (texture._depth>1 || texture._spectrum<_spectrum)
29589 "draw_triangle(): Invalid specified texture (%u,%u,%u,%u,%p).",
29591 texture._width,texture._height,texture._depth,texture._spectrum,texture._data);
29592 if (
is_overlapped(texture))
return draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,+texture,tx0,ty0,tx1,ty1,tx2,ty2,opacity,brightness);
29596 nbrightness = brightness<0?0:(brightness>2?2:brightness);
29597 const long whd = (long)_width*_height*_depth, twhd = (
long)texture._width*texture._height*texture._depth, offx = _spectrum*whd;
29598 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2;
29600 ntx0 = tx0/z0, nty0 = ty0/z0,
29601 ntx1 = tx1/z1, nty1 = ty1/z1,
29602 ntx2 = tx2/z2, nty2 = ty2/z2;
29603 tzfloat nz0 = 1/(tzfloat)z0, nz1 = 1/(tzfloat)z1, nz2 = 1/(tzfloat)z2;
29604 if (ny0>ny1)
cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nz0,nz1);
29605 if (ny0>ny2)
cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nz0,nz2);
29606 if (ny1>ny2)
cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nz1,nz2);
29607 if (ny0>=
height() || ny2<0)
return *
this;
29609 ptxl = (ntx1 - ntx0)/(ny1 - ny0),
29610 ptxr = (ntx2 - ntx0)/(ny2 - ny0),
29611 ptxn = (ntx2 - ntx1)/(ny2 - ny1),
29612 ptyl = (nty1 - nty0)/(ny1 - ny0),
29613 ptyr = (nty2 - nty0)/(ny2 - ny0),
29614 ptyn = (nty2 - nty1)/(ny2 - ny1),
29615 txr = ny0>=0?ntx0:(ntx0 - ny0*(ntx2 - ntx0)/(ny2 - ny0)),
29616 tyr = ny0>=0?nty0:(nty0 - ny0*(nty2 - nty0)/(ny2 - ny0)),
29617 txl = ny1>=0?(ny0>=0?ntx0:(ntx0 - ny0*(ntx1 - ntx0)/(ny1 - ny0))):(ptxl=ptxn,(ntx1 - ny1*(ntx2 - ntx1)/(ny2 - ny1))),
29618 tyl = ny1>=0?(ny0>=0?nty0:(nty0 - ny0*(nty1 - nty0)/(ny1 - ny0))):(ptyl=ptyn,(nty1 - ny1*(nty2 - nty1)/(ny2 - ny1)));
29620 pzl = (nz1 - nz0)/(ny1 - ny0),
29621 pzr = (nz2 - nz0)/(ny2 - ny0),
29622 pzn = (nz2 - nz1)/(ny2 - ny1),
29623 zr = ny0>=0?nz0:(nz0 - ny0*(nz2 - nz0)/(ny2 - ny0)),
29624 zl = ny1>=0?(ny0>=0?nz0:(nz0 - ny0*(nz1 - nz0)/(ny1 - ny0))):(pzl=pzn,(nz1 - ny1*(nz2 - nz1)/(ny2 - ny1)));
29625 _cimg_for_triangle1(*
this,xleft0,xright0,y,nx0,ny0,nx1,ny1,nx2,ny2) {
29626 if (y==ny1) { zl = nz1; txl = ntx1; tyl = nty1; pzl = pzn; ptxl = ptxn; ptyl = ptyn; }
29627 int xleft = xleft0, xright = xright0;
29628 float txleft = txl, txright = txr, tyleft = tyl, tyright = tyr;
29629 tzfloat zleft = zl, zright = zr;
29630 if (xright<xleft)
cimg::swap(xleft,xright,zleft,zright,txleft,txright,tyleft,tyright);
29631 const int dx = xright - xleft;
29632 const float pentetx = (txright - txleft)/dx, pentety = (tyright - tyleft)/dx;
29633 const tzfloat pentez = (zright - zleft)/dx;
29634 if (xleft<0 && dx) {
29635 zleft-=xleft*(zright - zleft)/dx;
29636 txleft-=xleft*(txright - txleft)/dx;
29637 tyleft-=xleft*(tyright - tyleft)/dx;
29639 if (xleft<0) xleft = 0;
29641 T *ptrd =
data(xleft,y,0,0);
29642 tz *ptrz = zbuffer.data(xleft,y);
29644 if (nbrightness==1)
for (
int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) {
29645 if (zleft>=(tzfloat)*ptrz) {
29647 const tzfloat invz = 1/zleft;
29648 const tc *col = texture.data((
int)(txleft*invz),(
int)(tyleft*invz));
29649 cimg_forC(*
this,c) {
29651 ptrd+=whd; col+=twhd;
29655 zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
29656 }
else if (nbrightness<1)
for (
int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) {
29657 if (zleft>=(tzfloat)*ptrz) {
29659 const tzfloat invz = 1/zleft;
29660 const tc *col = texture.data((
int)(txleft*invz),(
int)(tyleft*invz));
29661 cimg_forC(*
this,c) {
29662 *ptrd = (T)(nbrightness**col);
29663 ptrd+=whd; col+=twhd;
29667 zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
29668 }
else for (
int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) {
29669 if (zleft>=(tzfloat)*ptrz) {
29671 const tzfloat invz = 1/zleft;
29672 const tc *col = texture.data((
int)(txleft*invz),(
int)(tyleft*invz));
29673 cimg_forC(*
this,c) {
29674 *ptrd = (T)((2-nbrightness)**col + (nbrightness-1)*maxval);
29675 ptrd+=whd; col+=twhd;
29679 zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
29682 if (nbrightness==1)
for (
int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) {
29683 if (zleft>=(tzfloat)*ptrz) {
29685 const tzfloat invz = 1/zleft;
29686 const tc *col = texture.data((
int)(txleft*invz),(
int)(tyleft*invz));
29687 cimg_forC(*
this,c) {
29688 *ptrd = (T)(nopacity**col + *ptrd*copacity);
29689 ptrd+=whd; col+=twhd;
29693 zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
29694 }
else if (nbrightness<1)
for (
int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) {
29695 if (zleft>=(tzfloat)*ptrz) {
29697 const tzfloat invz = 1/zleft;
29698 const tc *col = texture.data((
int)(txleft*invz),(
int)(tyleft*invz));
29699 cimg_forC(*
this,c) {
29700 *ptrd = (T)(nopacity*nbrightness**col + *ptrd*copacity);
29701 ptrd+=whd; col+=twhd;
29705 zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
29706 }
else for (
int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) {
29707 if (zleft>=(tzfloat)*ptrz) {
29709 const tzfloat invz = 1/zleft;
29710 const tc *col = texture.data((
int)(txleft*invz),(
int)(tyleft*invz));
29711 cimg_forC(*
this,c) {
29712 const T val = (T)((2-nbrightness)**col + (nbrightness-1)*maxval);
29713 *ptrd = (T)(nopacity*val + *ptrd*copacity);
29714 ptrd+=whd; col+=twhd;
29718 zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
29721 zr+=pzr; txr+=ptxr; tyr+=ptyr; zl+=pzl; txl+=ptxl; tyl+=ptyl;
29744 template<
typename tc,
typename tl>
29746 const int x1,
const int y1,
29747 const int x2,
const int y2,
29748 const tc *
const color,
29750 const int lx0,
const int ly0,
29751 const int lx1,
const int ly1,
29752 const int lx2,
const int ly2,
29753 const float opacity=1) {
29757 "draw_triangle(): Specified color is (null).",
29759 if (light._depth>1 || light._spectrum<_spectrum)
29761 "draw_triangle(): Invalid specified light texture (%u,%u,%u,%u,%p).",
29762 cimg_instance,light._width,light._height,light._depth,light._spectrum,light._data);
29763 if (
is_overlapped(light))
return draw_triangle(x0,y0,x1,y1,x2,y2,color,+light,lx0,ly0,lx1,ly1,lx2,ly2,opacity);
29766 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2,
29767 nlx0 = lx0, nly0 = ly0, nlx1 = lx1, nly1 = ly1, nlx2 = lx2, nly2 = ly2;
29768 const long whd = (long)_width*_height*_depth, offx = _spectrum*whd-1;
29769 if (ny0>ny1)
cimg::swap(nx0,nx1,ny0,ny1,nlx0,nlx1,nly0,nly1);
29770 if (ny0>ny2)
cimg::swap(nx0,nx2,ny0,ny2,nlx0,nlx2,nly0,nly2);
29771 if (ny1>ny2)
cimg::swap(nx1,nx2,ny1,ny2,nlx1,nlx2,nly1,nly2);
29772 if (ny0>=
height() || ny2<0)
return *
this;
29773 _cimg_for_triangle3(*
this,xleft0,lxleft0,lyleft0,xright0,lxright0,lyright0,y,
29774 nx0,ny0,nlx0,nly0,nx1,ny1,nlx1,nly1,nx2,ny2,nlx2,nly2) {
29776 xleft = xleft0, xright = xright0,
29777 lxleft = lxleft0, lxright = lxright0,
29778 lyleft = lyleft0, lyright = lyright0;
29779 if (xright<xleft)
cimg::swap(xleft,xright,lxleft,lxright,lyleft,lyright);
29781 dx = xright - xleft,
29782 dlx = lxright>lxleft?lxright - lxleft:lxleft - lxright,
29783 dly = lyright>lyleft?lyright - lyleft:lyleft - lyright,
29784 rlx = dx?(lxright - lxleft)/dx:0,
29785 rly = dx?(lyright - lyleft)/dx:0,
29786 slx = lxright>lxleft?1:-1,
29787 sly = lyright>lyleft?1:-1,
29788 ndlx = dlx - (dx?dx*(dlx/dx):0),
29789 ndly = dly - (dx?dx*(dly/dx):0);
29790 int errlx = dx>>1, errly = errlx;
29791 if (xleft<0 && dx) {
29792 lxleft-=xleft*(lxright - lxleft)/dx;
29793 lyleft-=xleft*(lyright - lyleft)/dx;
29795 if (xleft<0) xleft = 0;
29797 T* ptrd =
data(xleft,y,0,0);
29798 if (opacity>=1)
for (
int x = xleft; x<=xright; ++x) {
29799 const tc *col = color;
29800 cimg_forC(*
this,c) {
29801 const tl l = light(lxleft,lyleft,c);
29802 *ptrd = (T)(l<1?l**(col++):((2-l)**(col++)+(l-1)*maxval));
29806 lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0);
29807 lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0);
29808 }
else for (
int x = xleft; x<=xright; ++x) {
29809 const tc *col = color;
29810 cimg_forC(*
this,c) {
29811 const tl l = light(lxleft,lyleft,c);
29812 const T val = (T)(l<1?l**(col++):((2-l)**(col++)+(l-1)*maxval));
29813 *ptrd = (T)(nopacity*val + *ptrd*copacity);
29817 lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0);
29818 lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0);
29825 template<
typename tz,
typename tc,
typename tl>
29827 const int x0,
const int y0,
const float z0,
29828 const int x1,
const int y1,
const float z1,
29829 const int x2,
const int y2,
const float z2,
29830 const tc *
const color,
29832 const int lx0,
const int ly0,
29833 const int lx1,
const int ly1,
29834 const int lx2,
const int ly2,
29835 const float opacity=1) {
29836 typedef typename cimg::superset<tz,float>::type tzfloat;
29837 if (
is_empty() || z0<=0 || z1<=0 || z2<=0)
return *
this;
29840 "draw_triangle(): Specified color is (null).",
29842 if (light._depth>1 || light._spectrum<_spectrum)
29844 "draw_triangle(): Invalid specified light texture (%u,%u,%u,%u,%p).",
29845 cimg_instance,light._width,light._height,light._depth,light._spectrum,light._data);
29848 "draw_triangle(): Instance and specified Z-buffer (%u,%u,%u,%u,%p) have different dimensions.",
29850 zbuffer._width,zbuffer._height,zbuffer._depth,zbuffer._spectrum,zbuffer._data);
29851 if (
is_overlapped(light))
return draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,color,
29852 +light,lx0,ly0,lx1,ly1,lx2,ly2,opacity);
29855 const long whd = (long)_width*_height*_depth, offx = _spectrum*whd;
29856 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2,
29857 nlx0 = lx0, nly0 = ly0, nlx1 = lx1, nly1 = ly1, nlx2 = lx2, nly2 = ly2;
29858 tzfloat nz0 = 1/(tzfloat)z0, nz1 = 1/(tzfloat)z1, nz2 = 1/(tzfloat)z2;
29859 if (ny0>ny1)
cimg::swap(nx0,nx1,ny0,ny1,nlx0,nlx1,nly0,nly1,nz0,nz1);
29860 if (ny0>ny2)
cimg::swap(nx0,nx2,ny0,ny2,nlx0,nlx2,nly0,nly2,nz0,nz2);
29861 if (ny1>ny2)
cimg::swap(nx1,nx2,ny1,ny2,nlx1,nlx2,nly1,nly2,nz1,nz2);
29862 if (ny0>=
height() || ny2<0)
return *
this;
29864 pzl = (nz1 - nz0)/(ny1 - ny0),
29865 pzr = (nz2 - nz0)/(ny2 - ny0),
29866 pzn = (nz2 - nz1)/(ny2 - ny1),
29867 zr = ny0>=0?nz0:(nz0 - ny0*(nz2 - nz0)/(ny2 - ny0)),
29868 zl = ny1>=0?(ny0>=0?nz0:(nz0 - ny0*(nz1 - nz0)/(ny1 - ny0))):(pzl=pzn,(nz1 - ny1*(nz2 - nz1)/(ny2 - ny1)));
29869 _cimg_for_triangle3(*
this,xleft0,lxleft0,lyleft0,xright0,lxright0,lyright0,y,
29870 nx0,ny0,nlx0,nly0,nx1,ny1,nlx1,nly1,nx2,ny2,nlx2,nly2) {
29871 if (y==ny1) { zl = nz1; pzl = pzn; }
29873 xleft = xleft0, xright = xright0,
29874 lxleft = lxleft0, lxright = lxright0,
29875 lyleft = lyleft0, lyright = lyright0;
29876 tzfloat zleft = zl, zright = zr;
29877 if (xright<xleft)
cimg::swap(xleft,xright,zleft,zright,lxleft,lxright,lyleft,lyright);
29879 dx = xright - xleft,
29880 dlx = lxright>lxleft?lxright - lxleft:lxleft - lxright,
29881 dly = lyright>lyleft?lyright - lyleft:lyleft - lyright,
29882 rlx = dx?(lxright - lxleft)/dx:0,
29883 rly = dx?(lyright - lyleft)/dx:0,
29884 slx = lxright>lxleft?1:-1,
29885 sly = lyright>lyleft?1:-1,
29886 ndlx = dlx - (dx?dx*(dlx/dx):0),
29887 ndly = dly - (dx?dx*(dly/dx):0);
29888 const tzfloat pentez = (zright - zleft)/dx;
29889 int errlx = dx>>1, errly = errlx;
29890 if (xleft<0 && dx) {
29891 zleft-=xleft*(zright - zleft)/dx;
29892 lxleft-=xleft*(lxright - lxleft)/dx;
29893 lyleft-=xleft*(lyright - lyleft)/dx;
29895 if (xleft<0) xleft = 0;
29897 T *ptrd =
data(xleft,y,0,0);
29898 tz *ptrz = zbuffer.data(xleft,y);
29899 if (opacity>=1)
for (
int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) {
29900 if (zleft>=(tzfloat)*ptrz) {
29902 const tc *col = color;
29903 cimg_forC(*
this,c) {
29904 const tl l = light(lxleft,lyleft,c);
29905 const tc cval = *(col++);
29906 *ptrd = (T)(l<1?l*cval:(2-l)*cval+(l-1)*maxval);
29912 lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0);
29913 lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0);
29914 }
else for (
int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) {
29915 if (zleft>=(tzfloat)*ptrz) {
29917 const tc *col = color;
29918 cimg_forC(*
this,c) {
29919 const tl l = light(lxleft,lyleft,c);
29920 const tc cval = *(col++);
29921 const T val = (T)(l<1?l*cval:(2-l)*cval+(l-1)*maxval);
29922 *ptrd = (T)(nopacity*val + *ptrd*copacity);
29928 lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0);
29929 lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0);
29956 template<
typename tc>
29958 const int x1,
const int y1,
29959 const int x2,
const int y2,
29961 const int tx0,
const int ty0,
29962 const int tx1,
const int ty1,
29963 const int tx2,
const int ty2,
29964 const float brightness0,
29965 const float brightness1,
29966 const float brightness2,
29967 const float opacity=1) {
29969 if (texture._depth>1 || texture._spectrum<_spectrum)
29971 "draw_triangle(): Invalid specified texture (%u,%u,%u,%u,%p).",
29973 texture._width,texture._height,texture._depth,texture._spectrum,texture._data);
29975 return draw_triangle(x0,y0,x1,y1,x2,y2,+texture,tx0,ty0,tx1,ty1,tx2,ty2,brightness0,brightness1,brightness2,opacity);
29978 const long whd = (long)_width*_height*_depth, twhd = (
long)texture._width*texture._height*texture._depth, offx = _spectrum*whd-1;
29979 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2,
29980 ntx0 = tx0, nty0 = ty0, ntx1 = tx1, nty1 = ty1, ntx2 = tx2, nty2 = ty2,
29981 nc0 = (int)((brightness0<0.0f?0.0f:(brightness0>2.0f?2.0f:brightness0))*256.0f),
29982 nc1 = (int)((brightness1<0.0f?0.0f:(brightness1>2.0f?2.0f:brightness1))*256.0f),
29983 nc2 = (int)((brightness2<0.0f?0.0f:(brightness2>2.0f?2.0f:brightness2))*256.0f);
29984 if (ny0>ny1)
cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nc0,nc1);
29985 if (ny0>ny2)
cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nc0,nc2);
29986 if (ny1>ny2)
cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nc1,nc2);
29987 if (ny0>=
height() || ny2<0)
return *
this;
29988 _cimg_for_triangle4(*
this,xleft0,cleft0,txleft0,tyleft0,xright0,cright0,txright0,tyright0,y,
29989 nx0,ny0,nc0,ntx0,nty0,nx1,ny1,nc1,ntx1,nty1,nx2,ny2,nc2,ntx2,nty2) {
29991 xleft = xleft0, xright = xright0,
29992 cleft = cleft0, cright = cright0,
29993 txleft = txleft0, txright = txright0,
29994 tyleft = tyleft0, tyright = tyright0;
29995 if (xright<xleft)
cimg::swap(xleft,xright,cleft,cright,txleft,txright,tyleft,tyright);
29997 dx = xright - xleft,
29998 dc = cright>cleft?cright - cleft:cleft - cright,
29999 dtx = txright>txleft?txright - txleft:txleft - txright,
30000 dty = tyright>tyleft?tyright - tyleft:tyleft - tyright,
30001 rc = dx?(cright - cleft)/dx:0,
30002 rtx = dx?(txright - txleft)/dx:0,
30003 rty = dx?(tyright - tyleft)/dx:0,
30004 sc = cright>cleft?1:-1,
30005 stx = txright>txleft?1:-1,
30006 sty = tyright>tyleft?1:-1,
30007 ndc = dc - (dx?dx*(dc/dx):0),
30008 ndtx = dtx - (dx?dx*(dtx/dx):0),
30009 ndty = dty - (dx?dx*(dty/dx):0);
30010 int errc = dx>>1, errtx = errc, errty = errc;
30011 if (xleft<0 && dx) {
30012 cleft-=xleft*(cright - cleft)/dx;
30013 txleft-=xleft*(txright - txleft)/dx;
30014 tyleft-=xleft*(tyright - tyleft)/dx;
30016 if (xleft<0) xleft = 0;
30018 T* ptrd =
data(xleft,y,0,0);
30019 if (opacity>=1)
for (
int x = xleft; x<=xright; ++x) {
30020 const tc *col = texture.data(txleft,tyleft);
30021 cimg_forC(*
this,c) {
30022 *ptrd = (T)(cleft<256?cleft**col/256:((512-cleft)**col+(cleft-256)*maxval)/256);
30023 ptrd+=whd; col+=twhd;
30026 cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0);
30027 txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0);
30028 tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0);
30029 }
else for (
int x = xleft; x<=xright; ++x) {
30030 const tc *col = texture.data(txleft,tyleft);
30031 cimg_forC(*
this,c) {
30032 const T val = (T)(cleft<256?cleft**col/256:((512-cleft)**col+(cleft-256)*maxval)/256);
30033 *ptrd = (T)(nopacity*val + *ptrd*copacity);
30034 ptrd+=whd; col+=twhd;
30037 cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0);
30038 txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0);
30039 tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0);
30046 template<
typename tc>
30048 const int x1,
const int y1,
const float z1,
30049 const int x2,
const int y2,
const float z2,
30051 const int tx0,
const int ty0,
30052 const int tx1,
const int ty1,
30053 const int tx2,
const int ty2,
30054 const float brightness0,
30055 const float brightness1,
30056 const float brightness2,
30057 const float opacity=1) {
30058 if (
is_empty() || z0<=0 || z1<=0 || z2<=0)
return *
this;
30059 if (texture._depth>1 || texture._spectrum<_spectrum)
30061 "draw_triangle(): Invalid specified texture (%u,%u,%u,%u,%p).",
30063 texture._width,texture._height,texture._depth,texture._spectrum,texture._data);
30064 if (
is_overlapped(texture))
return draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,+texture,tx0,ty0,tx1,ty1,tx2,ty2,
30065 brightness0,brightness1,brightness2,opacity);
30068 const long whd = (long)_width*_height*_depth, twhd = (
long)texture._width*texture._height*texture._depth, offx = _spectrum*whd-1;
30069 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2,
30070 nc0 = (int)((brightness0<0.0f?0.0f:(brightness0>2.0f?2.0f:brightness0))*256.0f),
30071 nc1 = (int)((brightness1<0.0f?0.0f:(brightness1>2.0f?2.0f:brightness1))*256.0f),
30072 nc2 = (int)((brightness2<0.0f?0.0f:(brightness2>2.0f?2.0f:brightness2))*256.0f);
30074 ntx0 = tx0/z0, nty0 = ty0/z0,
30075 ntx1 = tx1/z1, nty1 = ty1/z1,
30076 ntx2 = tx2/z2, nty2 = ty2/z2,
30077 nz0 = 1/z0, nz1 = 1/z1, nz2 = 1/z2;
30078 if (ny0>ny1)
cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nz0,nz1,nc0,nc1);
30079 if (ny0>ny2)
cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nz0,nz2,nc0,nc2);
30080 if (ny1>ny2)
cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nz1,nz2,nc1,nc2);
30081 if (ny0>=
height() || ny2<0)
return *
this;
30083 ptxl = (ntx1 - ntx0)/(ny1 - ny0),
30084 ptxr = (ntx2 - ntx0)/(ny2 - ny0),
30085 ptxn = (ntx2 - ntx1)/(ny2 - ny1),
30086 ptyl = (nty1 - nty0)/(ny1 - ny0),
30087 ptyr = (nty2 - nty0)/(ny2 - ny0),
30088 ptyn = (nty2 - nty1)/(ny2 - ny1),
30089 pzl = (nz1 - nz0)/(ny1 - ny0),
30090 pzr = (nz2 - nz0)/(ny2 - ny0),
30091 pzn = (nz2 - nz1)/(ny2 - ny1),
30092 zr = ny0>=0?nz0:(nz0 - ny0*(nz2 - nz0)/(ny2 - ny0)),
30093 txr = ny0>=0?ntx0:(ntx0 - ny0*(ntx2 - ntx0)/(ny2 - ny0)),
30094 tyr = ny0>=0?nty0:(nty0 - ny0*(nty2 - nty0)/(ny2 - ny0)),
30095 zl = ny1>=0?(ny0>=0?nz0:(nz0 - ny0*(nz1 - nz0)/(ny1 - ny0))):(pzl=pzn,(nz1 - ny1*(nz2 - nz1)/(ny2 - ny1))),
30096 txl = ny1>=0?(ny0>=0?ntx0:(ntx0 - ny0*(ntx1 - ntx0)/(ny1 - ny0))):(ptxl=ptxn,(ntx1 - ny1*(ntx2 - ntx1)/(ny2 - ny1))),
30097 tyl = ny1>=0?(ny0>=0?nty0:(nty0 - ny0*(nty1 - nty0)/(ny1 - ny0))):(ptyl=ptyn,(nty1 - ny1*(nty2 - nty1)/(ny2 - ny1)));
30098 _cimg_for_triangle2(*
this,xleft0,cleft0,xright0,cright0,y,nx0,ny0,nc0,nx1,ny1,nc1,nx2,ny2,nc2) {
30099 if (y==ny1) { zl = nz1; txl = ntx1; tyl = nty1; pzl = pzn; ptxl = ptxn; ptyl = ptyn; }
30101 xleft = xleft0, xright = xright0,
30102 cleft = cleft0, cright = cright0;
30104 zleft = zl, zright = zr,
30105 txleft = txl, txright = txr,
30106 tyleft = tyl, tyright = tyr;
30107 if (xright<xleft)
cimg::swap(xleft,xright,zleft,zright,txleft,txright,tyleft,tyright,cleft,cright);
30109 dx = xright - xleft,
30110 dc = cright>cleft?cright - cleft:cleft - cright,
30111 rc = dx?(cright - cleft)/dx:0,
30112 sc = cright>cleft?1:-1,
30113 ndc = dc - (dx?dx*(dc/dx):0);
30115 pentez = (zright - zleft)/dx,
30116 pentetx = (txright - txleft)/dx,
30117 pentety = (tyright - tyleft)/dx;
30119 if (xleft<0 && dx) {
30120 cleft-=xleft*(cright - cleft)/dx;
30121 zleft-=xleft*(zright - zleft)/dx;
30122 txleft-=xleft*(txright - txleft)/dx;
30123 tyleft-=xleft*(tyright - tyleft)/dx;
30125 if (xleft<0) xleft = 0;
30127 T* ptrd =
data(xleft,y,0,0);
30128 if (opacity>=1)
for (
int x = xleft; x<=xright; ++x) {
30129 const float invz = 1/zleft;
30130 const tc *col = texture.data((
int)(txleft*invz),(
int)(tyleft*invz));
30131 cimg_forC(*
this,c) {
30132 *ptrd = (T)(cleft<256?cleft**col/256:((512-cleft)**col+(cleft-256)*maxval)/256);
30133 ptrd+=whd; col+=twhd;
30135 ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
30136 cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0);
30137 }
else for (
int x = xleft; x<=xright; ++x) {
30138 const float invz = 1/zleft;
30139 const tc *col = texture.data((
int)(txleft*invz),(
int)(tyleft*invz));
30140 cimg_forC(*
this,c) {
30141 const T val = (T)(cleft<256?cleft**col/256:((512-cleft)**col+(cleft-256)*maxval)/256);
30142 *ptrd = (T)(nopacity*val + *ptrd*copacity);
30143 ptrd+=whd; col+=twhd;
30145 ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
30146 cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0);
30148 zr+=pzr; txr+=ptxr; tyr+=ptyr; zl+=pzl; txl+=ptxl; tyl+=ptyl;
30154 template<
typename tz,
typename tc>
30156 const int x0,
const int y0,
const float z0,
30157 const int x1,
const int y1,
const float z1,
30158 const int x2,
const int y2,
const float z2,
30160 const int tx0,
const int ty0,
30161 const int tx1,
const int ty1,
30162 const int tx2,
const int ty2,
30163 const float brightness0,
30164 const float brightness1,
30165 const float brightness2,
30166 const float opacity=1) {
30167 typedef typename cimg::superset<tz,float>::type tzfloat;
30168 if (
is_empty() || z0<=0 || z1<=0 || z2<=0)
return *
this;
30171 "draw_triangle(): Instance and specified Z-buffer (%u,%u,%u,%u,%p) have different dimensions.",
30173 zbuffer._width,zbuffer._height,zbuffer._depth,zbuffer._spectrum,zbuffer._data);
30174 if (texture._depth>1 || texture._spectrum<_spectrum)
30176 "draw_triangle(): Invalid specified texture (%u,%u,%u,%u,%p).",
30178 texture._width,texture._height,texture._depth,texture._spectrum,texture._data);
30179 if (
is_overlapped(texture))
return draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,+texture,tx0,ty0,tx1,ty1,tx2,ty2,
30180 brightness0,brightness1,brightness2,opacity);
30183 const long whd = (long)_width*_height*_depth, twhd = (
long)texture._width*texture._height*texture._depth, offx = _spectrum*whd;
30184 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2,
30185 nc0 = (int)((brightness0<0.0f?0.0f:(brightness0>2.0f?2.0f:brightness0))*256.0f),
30186 nc1 = (int)((brightness1<0.0f?0.0f:(brightness1>2.0f?2.0f:brightness1))*256.0f),
30187 nc2 = (int)((brightness2<0.0f?0.0f:(brightness2>2.0f?2.0f:brightness2))*256.0f);
30189 ntx0 = tx0/z0, nty0 = ty0/z0,
30190 ntx1 = tx1/z1, nty1 = ty1/z1,
30191 ntx2 = tx2/z2, nty2 = ty2/z2;
30192 tzfloat nz0 = 1/(tzfloat)z0, nz1 = 1/(tzfloat)z1, nz2 = 1/(tzfloat)z2;
30193 if (ny0>ny1)
cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nz0,nz1,nc0,nc1);
30194 if (ny0>ny2)
cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nz0,nz2,nc0,nc2);
30195 if (ny1>ny2)
cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nz1,nz2,nc1,nc2);
30196 if (ny0>=
height() || ny2<0)
return *
this;
30198 ptxl = (ntx1 - ntx0)/(ny1 - ny0),
30199 ptxr = (ntx2 - ntx0)/(ny2 - ny0),
30200 ptxn = (ntx2 - ntx1)/(ny2 - ny1),
30201 ptyl = (nty1 - nty0)/(ny1 - ny0),
30202 ptyr = (nty2 - nty0)/(ny2 - ny0),
30203 ptyn = (nty2 - nty1)/(ny2 - ny1),
30204 txr = ny0>=0?ntx0:(ntx0 - ny0*(ntx2 - ntx0)/(ny2 - ny0)),
30205 tyr = ny0>=0?nty0:(nty0 - ny0*(nty2 - nty0)/(ny2 - ny0)),
30206 txl = ny1>=0?(ny0>=0?ntx0:(ntx0 - ny0*(ntx1 - ntx0)/(ny1 - ny0))):(ptxl=ptxn,(ntx1 - ny1*(ntx2 - ntx1)/(ny2 - ny1))),
30207 tyl = ny1>=0?(ny0>=0?nty0:(nty0 - ny0*(nty1 - nty0)/(ny1 - ny0))):(ptyl=ptyn,(nty1 - ny1*(nty2 - nty1)/(ny2 - ny1)));
30209 pzl = (nz1 - nz0)/(ny1 - ny0),
30210 pzr = (nz2 - nz0)/(ny2 - ny0),
30211 pzn = (nz2 - nz1)/(ny2 - ny1),
30212 zr = ny0>=0?nz0:(nz0 - ny0*(nz2 - nz0)/(ny2 - ny0)),
30213 zl = ny1>=0?(ny0>=0?nz0:(nz0 - ny0*(nz1 - nz0)/(ny1 - ny0))):(pzl=pzn,(nz1 - ny1*(nz2 - nz1)/(ny2 - ny1)));
30214 _cimg_for_triangle2(*
this,xleft0,cleft0,xright0,cright0,y,nx0,ny0,nc0,nx1,ny1,nc1,nx2,ny2,nc2) {
30215 if (y==ny1) { zl = nz1; txl = ntx1; tyl = nty1; pzl = pzn; ptxl = ptxn; ptyl = ptyn; }
30216 int xleft = xleft0, xright = xright0, cleft = cleft0, cright = cright0;
30217 float txleft = txl, txright = txr, tyleft = tyl, tyright = tyr;
30218 tzfloat zleft = zl, zright = zr;
30219 if (xright<xleft)
cimg::swap(xleft,xright,zleft,zright,txleft,txright,tyleft,tyright,cleft,cright);
30221 dx = xright - xleft,
30222 dc = cright>cleft?cright - cleft:cleft - cright,
30223 rc = dx?(cright - cleft)/dx:0,
30224 sc = cright>cleft?1:-1,
30225 ndc = dc - (dx?dx*(dc/dx):0);
30226 float pentetx = (txright - txleft)/dx, pentety = (tyright - tyleft)/dx;
30227 const tzfloat pentez = (zright - zleft)/dx;
30229 if (xleft<0 && dx) {
30230 cleft-=xleft*(cright - cleft)/dx;
30231 zleft-=xleft*(zright - zleft)/dx;
30232 txleft-=xleft*(txright - txleft)/dx;
30233 tyleft-=xleft*(tyright - tyleft)/dx;
30235 if (xleft<0) xleft = 0;
30237 T* ptrd =
data(xleft,y);
30238 tz *ptrz = zbuffer.data(xleft,y);
30239 if (opacity>=1)
for (
int x = xleft; x<=xright; ++x, ++ptrd, ++ptrz) {
30240 if (zleft>=(tzfloat)*ptrz) {
30242 const tzfloat invz = 1/zleft;
30243 const tc *col = texture.data((
int)(txleft*invz),(
int)(tyleft*invz));
30244 cimg_forC(*
this,c) {
30245 *ptrd = (T)(cleft<256?cleft**col/256:((512-cleft)**col+(cleft-256)*maxval)/256);
30246 ptrd+=whd; col+=twhd;
30250 zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
30251 cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0);
30252 }
else for (
int x = xleft; x<=xright; ++x, ++ptrd, ++ptrz) {
30253 if (zleft>=(tzfloat)*ptrz) {
30255 const tzfloat invz = 1/zleft;
30256 const tc *col = texture.data((
int)(txleft*invz),(
int)(tyleft*invz));
30257 cimg_forC(*
this,c) {
30258 const T val = (T)(cleft<256?cleft**col/256:((512-cleft)**col+(cleft-256)*maxval)/256);
30259 *ptrd = (T)(nopacity*val + *ptrd*copacity);
30260 ptrd+=whd; col+=twhd;
30264 zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
30265 cleft+=rc+((errc-=ndc)<0?errc+=dx,sc:0);
30267 zr+=pzr; txr+=ptxr; tyr+=ptyr; zl+=pzl; txl+=ptxl; tyl+=ptyl;
30296 template<
typename tc,
typename tl>
30298 const int x1,
const int y1,
30299 const int x2,
const int y2,
30301 const int tx0,
const int ty0,
30302 const int tx1,
const int ty1,
30303 const int tx2,
const int ty2,
30305 const int lx0,
const int ly0,
30306 const int lx1,
const int ly1,
30307 const int lx2,
const int ly2,
30308 const float opacity=1) {
30310 if (texture._depth>1 || texture._spectrum<_spectrum)
30312 "draw_triangle(): Invalid specified texture (%u,%u,%u,%u,%p).",
30314 texture._width,texture._height,texture._depth,texture._spectrum,texture._data);
30315 if (light._depth>1 || light._spectrum<_spectrum)
30317 "draw_triangle(): Invalid specified light texture (%u,%u,%u,%u,%p).",
30318 cimg_instance,light._width,light._height,light._depth,light._spectrum,light._data);
30319 if (
is_overlapped(texture))
return draw_triangle(x0,y0,x1,y1,x2,y2,+texture,tx0,ty0,tx1,ty1,tx2,ty2,light,lx0,ly0,lx1,ly1,lx2,ly2,opacity);
30320 if (
is_overlapped(light))
return draw_triangle(x0,y0,x1,y1,x2,y2,texture,tx0,ty0,tx1,ty1,tx2,ty2,+light,lx0,ly0,lx1,ly1,lx2,ly2,opacity);
30323 const long whd = (long)_width*_height*_depth, twhd = (
long)texture._width*texture._height*texture._depth, offx = _spectrum*whd-1;
30324 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2,
30325 ntx0 = tx0, nty0 = ty0, ntx1 = tx1, nty1 = ty1, ntx2 = tx2, nty2 = ty2,
30326 nlx0 = lx0, nly0 = ly0, nlx1 = lx1, nly1 = ly1, nlx2 = lx2, nly2 = ly2;
30327 if (ny0>ny1)
cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nlx0,nlx1,nly0,nly1);
30328 if (ny0>ny2)
cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nlx0,nlx2,nly0,nly2);
30329 if (ny1>ny2)
cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nlx1,nlx2,nly1,nly2);
30330 if (ny0>=
height() || ny2<0)
return *
this;
30331 _cimg_for_triangle5(*
this,xleft0,lxleft0,lyleft0,txleft0,tyleft0,xright0,lxright0,lyright0,txright0,tyright0,y,
30332 nx0,ny0,nlx0,nly0,ntx0,nty0,nx1,ny1,nlx1,nly1,ntx1,nty1,nx2,ny2,nlx2,nly2,ntx2,nty2) {
30334 xleft = xleft0, xright = xright0,
30335 lxleft = lxleft0, lxright = lxright0,
30336 lyleft = lyleft0, lyright = lyright0,
30337 txleft = txleft0, txright = txright0,
30338 tyleft = tyleft0, tyright = tyright0;
30339 if (xright<xleft)
cimg::swap(xleft,xright,lxleft,lxright,lyleft,lyright,txleft,txright,tyleft,tyright);
30341 dx = xright - xleft,
30342 dlx = lxright>lxleft?lxright - lxleft:lxleft - lxright,
30343 dly = lyright>lyleft?lyright - lyleft:lyleft - lyright,
30344 dtx = txright>txleft?txright - txleft:txleft - txright,
30345 dty = tyright>tyleft?tyright - tyleft:tyleft - tyright,
30346 rlx = dx?(lxright - lxleft)/dx:0,
30347 rly = dx?(lyright - lyleft)/dx:0,
30348 rtx = dx?(txright - txleft)/dx:0,
30349 rty = dx?(tyright - tyleft)/dx:0,
30350 slx = lxright>lxleft?1:-1,
30351 sly = lyright>lyleft?1:-1,
30352 stx = txright>txleft?1:-1,
30353 sty = tyright>tyleft?1:-1,
30354 ndlx = dlx - (dx?dx*(dlx/dx):0),
30355 ndly = dly - (dx?dx*(dly/dx):0),
30356 ndtx = dtx - (dx?dx*(dtx/dx):0),
30357 ndty = dty - (dx?dx*(dty/dx):0);
30358 int errlx = dx>>1, errly = errlx, errtx = errlx, errty = errlx;
30359 if (xleft<0 && dx) {
30360 lxleft-=xleft*(lxright - lxleft)/dx;
30361 lyleft-=xleft*(lyright - lyleft)/dx;
30362 txleft-=xleft*(txright - txleft)/dx;
30363 tyleft-=xleft*(tyright - tyleft)/dx;
30365 if (xleft<0) xleft = 0;
30367 T* ptrd =
data(xleft,y,0,0);
30368 if (opacity>=1)
for (
int x = xleft; x<=xright; ++x) {
30369 const tc *col = texture.data(txleft,tyleft);
30370 cimg_forC(*
this,c) {
30371 const tl l = light(lxleft,lyleft,c);
30372 *ptrd = (T)(l<1?l**col:(2-l)**col+(l-1)*maxval);
30373 ptrd+=whd; col+=twhd;
30376 lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0);
30377 lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0);
30378 txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0);
30379 tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0);
30380 }
else for (
int x = xleft; x<=xright; ++x) {
30381 const tc *col = texture.data(txleft,tyleft);
30382 cimg_forC(*
this,c) {
30383 const tl l = light(lxleft,lyleft,c);
30384 const T val = (T)(l<1?l**col:(2-l)**col+(l-1)*maxval);
30385 *ptrd = (T)(nopacity*val + *ptrd*copacity);
30386 ptrd+=whd; col+=twhd;
30389 lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0);
30390 lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0);
30391 txleft+=rtx+((errtx-=ndtx)<0?errtx+=dx,stx:0);
30392 tyleft+=rty+((errty-=ndty)<0?errty+=dx,sty:0);
30399 template<
typename tc,
typename tl>
30401 const int x1,
const int y1,
const float z1,
30402 const int x2,
const int y2,
const float z2,
30404 const int tx0,
const int ty0,
30405 const int tx1,
const int ty1,
30406 const int tx2,
const int ty2,
30408 const int lx0,
const int ly0,
30409 const int lx1,
const int ly1,
30410 const int lx2,
const int ly2,
30411 const float opacity=1) {
30412 if (
is_empty() || z0<=0 || z1<=0 || z2<=0)
return *
this;
30413 if (texture._depth>1 || texture._spectrum<_spectrum)
30415 "draw_triangle(): Invalid specified texture (%u,%u,%u,%u,%p).",
30417 texture._width,texture._height,texture._depth,texture._spectrum,texture._data);
30418 if (light._depth>1 || light._spectrum<_spectrum)
30420 "draw_triangle(): Invalid specified light texture (%u,%u,%u,%u,%p).",
30421 cimg_instance,light._width,light._height,light._depth,light._spectrum,light._data);
30422 if (
is_overlapped(texture))
return draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,+texture,tx0,ty0,tx1,ty1,tx2,ty2,light,lx0,ly0,lx1,ly1,lx2,ly2,opacity);
30423 if (
is_overlapped(light))
return draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,texture,tx0,ty0,tx1,ty1,tx2,ty2,+light,lx0,ly0,lx1,ly1,lx2,ly2,opacity);
30426 const long whd = (long)_width*_height*_depth, twhd = (
long)texture._width*texture._height*texture._depth, offx = _spectrum*whd-1;
30427 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2,
30428 nlx0 = lx0, nly0 = ly0, nlx1 = lx1, nly1 = ly1, nlx2 = lx2, nly2 = ly2;
30430 ntx0 = tx0/z0, nty0 = ty0/z0,
30431 ntx1 = tx1/z1, nty1 = ty1/z1,
30432 ntx2 = tx2/z2, nty2 = ty2/z2,
30433 nz0 = 1/z0, nz1 = 1/z1, nz2 = 1/z2;
30434 if (ny0>ny1)
cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nlx0,nlx1,nly0,nly1,nz0,nz1);
30435 if (ny0>ny2)
cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nlx0,nlx2,nly0,nly2,nz0,nz2);
30436 if (ny1>ny2)
cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nlx1,nlx2,nly1,nly2,nz1,nz2);
30437 if (ny0>=
height() || ny2<0)
return *
this;
30439 ptxl = (ntx1 - ntx0)/(ny1 - ny0),
30440 ptxr = (ntx2 - ntx0)/(ny2 - ny0),
30441 ptxn = (ntx2 - ntx1)/(ny2 - ny1),
30442 ptyl = (nty1 - nty0)/(ny1 - ny0),
30443 ptyr = (nty2 - nty0)/(ny2 - ny0),
30444 ptyn = (nty2 - nty1)/(ny2 - ny1),
30445 pzl = (nz1 - nz0)/(ny1 - ny0),
30446 pzr = (nz2 - nz0)/(ny2 - ny0),
30447 pzn = (nz2 - nz1)/(ny2 - ny1),
30448 zr = ny0>=0?nz0:(nz0 - ny0*(nz2 - nz0)/(ny2 - ny0)),
30449 txr = ny0>=0?ntx0:(ntx0 - ny0*(ntx2 - ntx0)/(ny2 - ny0)),
30450 tyr = ny0>=0?nty0:(nty0 - ny0*(nty2 - nty0)/(ny2 - ny0)),
30451 zl = ny1>=0?(ny0>=0?nz0:(nz0 - ny0*(nz1 - nz0)/(ny1 - ny0))):(pzl=pzn,(nz1 - ny1*(nz2 - nz1)/(ny2 - ny1))),
30452 txl = ny1>=0?(ny0>=0?ntx0:(ntx0 - ny0*(ntx1 - ntx0)/(ny1 - ny0))):(ptxl=ptxn,(ntx1 - ny1*(ntx2 - ntx1)/(ny2 - ny1))),
30453 tyl = ny1>=0?(ny0>=0?nty0:(nty0 - ny0*(nty1 - nty0)/(ny1 - ny0))):(ptyl=ptyn,(nty1 - ny1*(nty2 - nty1)/(ny2 - ny1)));
30454 _cimg_for_triangle3(*
this,xleft0,lxleft0,lyleft0,xright0,lxright0,lyright0,y,
30455 nx0,ny0,nlx0,nly0,nx1,ny1,nlx1,nly1,nx2,ny2,nlx2,nly2) {
30456 if (y==ny1) { zl = nz1; txl = ntx1; tyl = nty1; pzl = pzn; ptxl = ptxn; ptyl = ptyn; }
30458 xleft = xleft0, xright = xright0,
30459 lxleft = lxleft0, lxright = lxright0,
30460 lyleft = lyleft0, lyright = lyright0;
30462 zleft = zl, zright = zr,
30463 txleft = txl, txright = txr,
30464 tyleft = tyl, tyright = tyr;
30465 if (xright<xleft)
cimg::swap(xleft,xright,zleft,zright,txleft,txright,tyleft,tyright,lxleft,lxright,lyleft,lyright);
30467 dx = xright - xleft,
30468 dlx = lxright>lxleft?lxright - lxleft:lxleft - lxright,
30469 dly = lyright>lyleft?lyright - lyleft:lyleft - lyright,
30470 rlx = dx?(lxright - lxleft)/dx:0,
30471 rly = dx?(lyright - lyleft)/dx:0,
30472 slx = lxright>lxleft?1:-1,
30473 sly = lyright>lyleft?1:-1,
30474 ndlx = dlx - (dx?dx*(dlx/dx):0),
30475 ndly = dly - (dx?dx*(dly/dx):0);
30477 pentez = (zright - zleft)/dx,
30478 pentetx = (txright - txleft)/dx,
30479 pentety = (tyright - tyleft)/dx;
30480 int errlx = dx>>1, errly = errlx;
30481 if (xleft<0 && dx) {
30482 zleft-=xleft*(zright - zleft)/dx;
30483 lxleft-=xleft*(lxright - lxleft)/dx;
30484 lyleft-=xleft*(lyright - lyleft)/dx;
30485 txleft-=xleft*(txright - txleft)/dx;
30486 tyleft-=xleft*(tyright - tyleft)/dx;
30488 if (xleft<0) xleft = 0;
30490 T* ptrd =
data(xleft,y,0,0);
30491 if (opacity>=1)
for (
int x = xleft; x<=xright; ++x) {
30492 const float invz = 1/zleft;
30493 const tc *col = texture.data((
int)(txleft*invz),(
int)(tyleft*invz));
30494 cimg_forC(*
this,c) {
30495 const tl l = light(lxleft,lyleft,c);
30496 *ptrd = (T)(l<1?l**col:(2-l)**col+(l-1)*maxval);
30497 ptrd+=whd; col+=twhd;
30499 ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
30500 lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0);
30501 lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0);
30502 }
else for (
int x = xleft; x<=xright; ++x) {
30503 const float invz = 1/zleft;
30504 const tc *col = texture.data((
int)(txleft*invz),(
int)(tyleft*invz));
30505 cimg_forC(*
this,c) {
30506 const tl l = light(lxleft,lyleft,c);
30507 const T val = (T)(l<1?l**col:(2-l)**col+(l-1)*maxval);
30508 *ptrd = (T)(nopacity*val + *ptrd*copacity);
30509 ptrd+=whd; col+=twhd;
30511 ptrd-=offx; zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
30512 lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0);
30513 lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0);
30515 zr+=pzr; txr+=ptxr; tyr+=ptyr; zl+=pzl; txl+=ptxl; tyl+=ptyl;
30521 template<
typename tz,
typename tc,
typename tl>
30523 const int x0,
const int y0,
const float z0,
30524 const int x1,
const int y1,
const float z1,
30525 const int x2,
const int y2,
const float z2,
30527 const int tx0,
const int ty0,
30528 const int tx1,
const int ty1,
30529 const int tx2,
const int ty2,
30531 const int lx0,
const int ly0,
30532 const int lx1,
const int ly1,
30533 const int lx2,
const int ly2,
30534 const float opacity=1) {
30535 typedef typename cimg::superset<tz,float>::type tzfloat;
30536 if (
is_empty() || z0<=0 || z1<=0 || z2<=0)
return *
this;
30539 "draw_triangle(): Instance and specified Z-buffer (%u,%u,%u,%u,%p) have different dimensions.",
30541 zbuffer._width,zbuffer._height,zbuffer._depth,zbuffer._spectrum,zbuffer._data);
30542 if (texture._depth>1 || texture._spectrum<_spectrum)
30544 "draw_triangle(): Invalid specified texture (%u,%u,%u,%u,%p).",
30546 texture._width,texture._height,texture._depth,texture._spectrum,texture._data);
30547 if (light._depth>1 || light._spectrum<_spectrum)
30549 "draw_triangle(): Invalid specified light texture (%u,%u,%u,%u,%p).",
30550 cimg_instance,light._width,light._height,light._depth,light._spectrum,light._data);
30551 if (
is_overlapped(texture))
return draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,
30552 +texture,tx0,ty0,tx1,ty1,tx2,ty2,light,lx0,ly0,lx1,ly1,lx2,ly2,opacity);
30553 if (
is_overlapped(light))
return draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,
30554 texture,tx0,ty0,tx1,ty1,tx2,ty2,+light,lx0,ly0,lx1,ly1,lx2,ly2,opacity);
30557 const long whd = (long)_width*_height*_depth, twhd = (
long)texture._width*texture._height*texture._depth, offx = _spectrum*whd;
30558 int nx0 = x0, ny0 = y0, nx1 = x1, ny1 = y1, nx2 = x2, ny2 = y2,
30559 nlx0 = lx0, nly0 = ly0, nlx1 = lx1, nly1 = ly1, nlx2 = lx2, nly2 = ly2;
30561 ntx0 = tx0/z0, nty0 = ty0/z0,
30562 ntx1 = tx1/z1, nty1 = ty1/z1,
30563 ntx2 = tx2/z2, nty2 = ty2/z2;
30564 tzfloat nz0 = 1/(tzfloat)z0, nz1 = 1/(tzfloat)z1, nz2 = 1/(tzfloat)z2;
30565 if (ny0>ny1)
cimg::swap(nx0,nx1,ny0,ny1,ntx0,ntx1,nty0,nty1,nlx0,nlx1,nly0,nly1,nz0,nz1);
30566 if (ny0>ny2)
cimg::swap(nx0,nx2,ny0,ny2,ntx0,ntx2,nty0,nty2,nlx0,nlx2,nly0,nly2,nz0,nz2);
30567 if (ny1>ny2)
cimg::swap(nx1,nx2,ny1,ny2,ntx1,ntx2,nty1,nty2,nlx1,nlx2,nly1,nly2,nz1,nz2);
30568 if (ny0>=
height() || ny2<0)
return *
this;
30570 ptxl = (ntx1 - ntx0)/(ny1 - ny0),
30571 ptxr = (ntx2 - ntx0)/(ny2 - ny0),
30572 ptxn = (ntx2 - ntx1)/(ny2 - ny1),
30573 ptyl = (nty1 - nty0)/(ny1 - ny0),
30574 ptyr = (nty2 - nty0)/(ny2 - ny0),
30575 ptyn = (nty2 - nty1)/(ny2 - ny1),
30576 txr = ny0>=0?ntx0:(ntx0 - ny0*(ntx2 - ntx0)/(ny2 - ny0)),
30577 tyr = ny0>=0?nty0:(nty0 - ny0*(nty2 - nty0)/(ny2 - ny0)),
30578 txl = ny1>=0?(ny0>=0?ntx0:(ntx0 - ny0*(ntx1 - ntx0)/(ny1 - ny0))):(ptxl=ptxn,(ntx1 - ny1*(ntx2 - ntx1)/(ny2 - ny1))),
30579 tyl = ny1>=0?(ny0>=0?nty0:(nty0 - ny0*(nty1 - nty0)/(ny1 - ny0))):(ptyl=ptyn,(nty1 - ny1*(nty2 - nty1)/(ny2 - ny1)));
30581 pzl = (nz1 - nz0)/(ny1 - ny0),
30582 pzr = (nz2 - nz0)/(ny2 - ny0),
30583 pzn = (nz2 - nz1)/(ny2 - ny1),
30584 zr = ny0>=0?nz0:(nz0 - ny0*(nz2 - nz0)/(ny2 - ny0)),
30585 zl = ny1>=0?(ny0>=0?nz0:(nz0 - ny0*(nz1 - nz0)/(ny1 - ny0))):(pzl=pzn,(nz1 - ny1*(nz2 - nz1)/(ny2 - ny1)));
30586 _cimg_for_triangle3(*
this,xleft0,lxleft0,lyleft0,xright0,lxright0,lyright0,y,
30587 nx0,ny0,nlx0,nly0,nx1,ny1,nlx1,nly1,nx2,ny2,nlx2,nly2) {
30588 if (y==ny1) { zl = nz1; txl = ntx1; tyl = nty1; pzl = pzn; ptxl = ptxn; ptyl = ptyn; }
30590 xleft = xleft0, xright = xright0,
30591 lxleft = lxleft0, lxright = lxright0,
30592 lyleft = lyleft0, lyright = lyright0;
30593 float txleft = txl, txright = txr, tyleft = tyl, tyright = tyr;
30594 tzfloat zleft = zl, zright = zr;
30595 if (xright<xleft)
cimg::swap(xleft,xright,zleft,zright,txleft,txright,tyleft,tyright,lxleft,lxright,lyleft,lyright);
30597 dx = xright - xleft,
30598 dlx = lxright>lxleft?lxright - lxleft:lxleft - lxright,
30599 dly = lyright>lyleft?lyright - lyleft:lyleft - lyright,
30600 rlx = dx?(lxright - lxleft)/dx:0,
30601 rly = dx?(lyright - lyleft)/dx:0,
30602 slx = lxright>lxleft?1:-1,
30603 sly = lyright>lyleft?1:-1,
30604 ndlx = dlx - (dx?dx*(dlx/dx):0),
30605 ndly = dly - (dx?dx*(dly/dx):0);
30606 float pentetx = (txright - txleft)/dx, pentety = (tyright - tyleft)/dx;
30607 const tzfloat pentez = (zright - zleft)/dx;
30608 int errlx = dx>>1, errly = errlx;
30609 if (xleft<0 && dx) {
30610 zleft-=xleft*(zright - zleft)/dx;
30611 lxleft-=xleft*(lxright - lxleft)/dx;
30612 lyleft-=xleft*(lyright - lyleft)/dx;
30613 txleft-=xleft*(txright - txleft)/dx;
30614 tyleft-=xleft*(tyright - tyleft)/dx;
30616 if (xleft<0) xleft = 0;
30618 T* ptrd =
data(xleft,y);
30619 tz *ptrz = zbuffer.data(xleft,y);
30620 if (opacity>=1)
for (
int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) {
30621 if (zleft>=(tzfloat)*ptrz) {
30623 const tzfloat invz = 1/zleft;
30624 const tc *col = texture.data((
int)(txleft*invz),(
int)(tyleft*invz));
30625 cimg_forC(*
this,c) {
30626 const tl l = light(lxleft,lyleft,c);
30627 *ptrd = (T)(l<1?l**col:(2-l)**col+(l-1)*maxval);
30628 ptrd+=whd; col+=twhd;
30632 zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
30633 lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0);
30634 lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0);
30635 }
else for (
int x = xleft; x<=xright; ++x, ++ptrz, ++ptrd) {
30636 if (zleft>=(tzfloat)*ptrz) {
30638 const tzfloat invz = 1/zleft;
30639 const tc *col = texture.data((
int)(txleft*invz),(
int)(tyleft*invz));
30640 cimg_forC(*
this,c) {
30641 const tl l = light(lxleft,lyleft,c);
30642 const T val = (T)(l<1?l**col:(2-l)**col+(l-1)*maxval);
30643 *ptrd = (T)(nopacity*val + *ptrd*copacity);
30644 ptrd+=whd; col+=twhd;
30648 zleft+=pentez; txleft+=pentetx; tyleft+=pentety;
30649 lxleft+=rlx+((errlx-=ndlx)<0?errlx+=dx,slx:0);
30650 lyleft+=rly+((errly-=ndly)<0?errly+=dx,sly:0);
30652 zr+=pzr; txr+=ptxr; tyr+=ptyr; zl+=pzl; txl+=ptxl; tyl+=ptyl;
30671 const int x1,
const int y1,
const int z1,
const int c1,
30672 const T val,
const float opacity=1) {
30674 const bool bx = (x0<x1), by = (y0<y1), bz = (z0<z1), bc = (c0<c1);
30676 nx0 = bx?x0:x1, nx1 = bx?x1:x0,
30677 ny0 = by?y0:y1, ny1 = by?y1:y0,
30678 nz0 = bz?z0:z1, nz1 = bz?z1:z0,
30679 nc0 = bc?c0:c1, nc1 = bc?c1:c0;
30681 lX = (1 + nx1 - nx0) + (nx1>=
width()?
width() - 1 - nx1:0) + (nx0<0?nx0:0),
30682 lY = (1 + ny1 - ny0) + (ny1>=
height()?
height() - 1 - ny1:0) + (ny0<0?ny0:0),
30683 lZ = (1 + nz1 - nz0) + (nz1>=
depth()?
depth() - 1 - nz1:0) + (nz0<0?nz0:0),
30684 lC = (1 + nc1 - nc0) + (nc1>=
spectrum()?
spectrum() - 1 - nc1:0) + (nc0<0?nc0:0);
30685 const unsigned long
30686 offX = (
unsigned long)_width - lX,
30687 offY = (
unsigned long)_width*(_height - lY),
30688 offZ = (
unsigned long)_width*_height*(_depth - lZ);
30690 T *ptrd =
data(nx0<0?0:nx0,ny0<0?0:ny0,nz0<0?0:nz0,nc0<0?0:nc0);
30691 if (lX>0 && lY>0 && lZ>0 && lC>0)
30692 for (
int v = 0; v<lC; ++v) {
30693 for (
int z = 0; z<lZ; ++z) {
30694 for (
int y = 0; y<lY; ++y) {
30696 if (
sizeof(T)!=1) {
for (
int x = 0; x<lX; ++x) *(ptrd++) = val; ptrd+=offX; }
30697 else { std::memset(ptrd,(
int)val,lX); ptrd+=_width; }
30698 }
else {
for (
int x = 0; x<lX; ++x) { *ptrd = (T)(nopacity*val + *ptrd*copacity); ++ptrd; } ptrd+=offX; }
30718 template<
typename tc>
30720 const int x1,
const int y1,
const int z1,
30721 const tc *
const color,
const float opacity=1) {
30725 "draw_rectangle(): Specified color is (null).",
30727 cimg_forC(*
this,c)
draw_rectangle(x0,y0,z0,c,x1,y1,z1,c,(T)color[c],opacity);
30732 template<
typename tc>
30734 const int x1,
const int y1,
const int z1,
30735 const tc *
const color,
const float opacity,
30736 const unsigned int pattern) {
30737 return draw_line(x0,y0,z0,x1,y0,z0,color,opacity,pattern,
true).
30738 draw_line(x1,y0,z0,x1,y1,z0,color,opacity,pattern,
false).
30739 draw_line(x1,y1,z0,x0,y1,z0,color,opacity,pattern,
false).
30740 draw_line(x0,y1,z0,x0,y0,z0,color,opacity,pattern,
false).
30741 draw_line(x0,y0,z1,x1,y0,z1,color,opacity,pattern,
true).
30742 draw_line(x1,y0,z1,x1,y1,z1,color,opacity,pattern,
false).
30743 draw_line(x1,y1,z1,x0,y1,z1,color,opacity,pattern,
false).
30744 draw_line(x0,y1,z1,x0,y0,z1,color,opacity,pattern,
false).
30745 draw_line(x0,y0,z0,x0,y0,z1,color,opacity,pattern,
true).
30746 draw_line(x1,y0,z0,x1,y0,z1,color,opacity,pattern,
true).
30747 draw_line(x1,y1,z0,x1,y1,z1,color,opacity,pattern,
true).
30748 draw_line(x0,y1,z0,x0,y1,z1,color,opacity,pattern,
true);
30760 template<
typename tc>
30762 const int x1,
const int y1,
30763 const tc *
const color,
const float opacity=1) {
30768 template<
typename tc>
30770 const int x1,
const int y1,
30771 const tc *
const color,
const float opacity,
30772 const unsigned int pattern) {
30774 if (y0==y1)
return draw_line(x0,y0,x1,y0,color,opacity,pattern,
true);
30775 if (x0==x1)
return draw_line(x0,y0,x0,y1,color,opacity,pattern,
true);
30776 const bool bx = (x0<x1), by = (y0<y1);
30778 nx0 = bx?x0:x1, nx1 = bx?x1:x0,
30779 ny0 = by?y0:y1, ny1 = by?y1:y0;
30780 if (ny1==ny0+1)
return draw_line(nx0,ny0,nx1,ny0,color,opacity,pattern,
true).
30781 draw_line(nx1,ny1,nx0,ny1,color,opacity,pattern,
false);
30782 return draw_line(nx0,ny0,nx1,ny0,color,opacity,pattern,
true).
30783 draw_line(nx1,ny0+1,nx1,ny1-1,color,opacity,pattern,
false).
30784 draw_line(nx1,ny1,nx0,ny1,color,opacity,pattern,
false).
30785 draw_line(nx0,ny1-1,nx0,ny0+1,color,opacity,pattern,
false);
30794 template<
typename t,
typename tc>
30796 const tc *
const color,
const float opacity=1) {
30797 if (
is_empty() || !points || points._width<3)
return *
this;
30800 "draw_polygon(): Specified color is (null).",
30805 int x = npoints(0,0) = (int)points(0,0), y = npoints(0,1) = (int)points(0,1);
30806 unsigned int nb_points = 1;
30807 for (
unsigned int p = 1; p<points._width; ++p) {
30808 const int nx = (int)points(p,0), ny = (int)points(p,1);
30809 if (nx!=x || ny!=y) { npoints(nb_points,0) = nx; npoints(nb_points++,1) = ny; x = nx; y = ny; }
30812 if (nb_points==3)
return draw_triangle((
int)npoints(0,0),(
int)npoints(0,1),
30813 (
int)npoints(1,0),(
int)npoints(1,1),
30814 (
int)npoints(2,0),(
int)npoints(2,1),color,opacity);
30816 _draw_scanline(color,opacity);
30818 xmax = 0, xmin = (int)npoints.get_shared_points(0,nb_points-1,0).min_max(xmax),
30819 ymax = 0, ymin = (int)npoints.get_shared_points(0,nb_points-1,1).min_max(ymax);
30820 if (xmax<0 || xmin>=
width() || ymax<0 || ymin>=
height())
return *
this;
30821 if (ymin==ymax)
return _draw_scanline(xmin,xmax,ymin,color,opacity);
30823 nymin = ymin<0?0:(
unsigned int)ymin,
30824 nymax = ymax>=
height()?_height-1:(
unsigned int)ymax,
30825 dy = 1 + nymax - nymin;
30827 int cx = (int)npoints(0,0), cy = (int)npoints(0,1);
30828 unsigned int cp = 0;
30829 for (
unsigned int p = 0; p<nb_points; ++p) {
30830 const unsigned int np = (p!=nb_points-1)?p+1:0, ap = (np!=nb_points-1)?np+1:0;
30832 nx = (int)npoints(np,0), ny = (int)npoints(np,1), ay = (int)npoints(ap,1),
30833 y0 = cy - nymin, y1 = ny - nymin;
30835 const int countermin = ((ny<ay && cy<ny) || (ny>ay && cy>ny))?1:0;
30836 for (
int x = cx, y = y0, _sx = 1, _sy = 1,
30837 _dx = nx>cx?nx-cx:((_sx=-1),cx-nx),
30838 _dy = y1>y0?y1-y0:((_sy=-1),y0-y1),
30839 _counter = ((_dx-=_dy?_dy*(_dx/_dy):0),_dy),
30841 _rx = _dy?(nx-cx)/_dy:0;
30842 _counter>=countermin;
30843 --_counter, y+=_sy, x+=_rx + ((_err-=_dx)<0?_err+=_dy,_sx:0))
30844 if (y>=0 && y<(
int)dy) X(++X(0,y),y) = x;
30845 cp = np; cx = nx; cy = ny;
30847 const int pp = (cp?cp-1:nb_points-1), py = (
int)npoints(pp,1);
30848 if (y0>=0 && y0<(
int)dy && (!p || (cy>py && ay>cy) || (cy<py && ay<cy))) X(++X(0,y0),y0) = nx;
30849 if (cy!=ay) { cp = np; cx = nx; cy = ny; }
30854 for (
int y = 0; y<(int)dy; ++y) {
30855 tmp.assign(X.data(1,y),X(0,y),1,1,1,
true).
sort();
30856 for (
int i = 1; i<=X(0,y); ) {
30857 const int xb = X(i++,y), xe = X(i++,y);
30858 _draw_scanline(xb,xe,nymin+y,color,opacity);
30866 template<
typename t,
typename tc>
30868 const tc *
const color,
const float opacity,
const unsigned int pattern) {
30869 if (
is_empty() || !points || points._width<3)
return *
this;
30870 bool ninit_hatch =
true;
30871 switch (points._height) {
30874 "draw_polygon(): Invalid specified point set.",
30878 int x = npoints(0,0) = (int)points(0,0), y = npoints(0,1) = (int)points(0,1);
30879 unsigned int nb_points = 1;
30880 for (
unsigned int p = 1; p<points._width; ++p) {
30881 const int nx = (int)points(p,0), ny = (int)points(p,1);
30882 if (nx!=x || ny!=y) { npoints(nb_points,0) = nx; npoints(nb_points++,1) = ny; x = nx; y = ny; }
30884 const int x0 = (int)npoints(0,0), y0 = (int)npoints(0,1);
30885 int ox = x0, oy = y0;
30886 for (
unsigned int i = 1; i<nb_points; ++i) {
30887 const int x = (int)npoints(i,0), y = (int)npoints(i,1);
30888 draw_line(ox,oy,x,y,color,opacity,pattern,ninit_hatch);
30889 ninit_hatch =
false;
30892 draw_line(ox,oy,x0,y0,color,opacity,pattern,
false);
30896 int x = npoints(0,0) = (int)points(0,0), y = npoints(0,1) = (int)points(0,1), z = npoints(0,2) = (int)points(0,2);
30897 unsigned int nb_points = 1;
30898 for (
unsigned int p = 1; p<points._width; ++p) {
30899 const int nx = (int)points(p,0), ny = (int)points(p,1), nz = (int)points(p,2);
30900 if (nx!=x || ny!=y || nz!=z) { npoints(nb_points,0) = nx; npoints(nb_points,1) = ny; npoints(nb_points++,2) = nz; x = nx; y = ny; z = nz; }
30902 const int x0 = (int)npoints(0,0), y0 = (int)npoints(0,1), z0 = (int)npoints(0,2);
30903 int ox = x0, oy = y0, oz = z0;
30904 for (
unsigned int i = 1; i<nb_points; ++i) {
30905 const int x = (int)npoints(i,0), y = (int)npoints(i,1), z = (int)npoints(i,2);
30906 draw_line(ox,oy,oz,x,y,z,color,opacity,pattern,ninit_hatch);
30907 ninit_hatch =
false;
30908 ox = x; oy = y; oz = z;
30910 draw_line(ox,oy,oz,x0,y0,z0,color,opacity,pattern,
false);
30926 template<
typename tc>
30928 const tc *
const color,
const float opacity=1) {
30929 return _draw_ellipse(x0,y0,r1,r2,angle,color,opacity,0U);
30940 template<
typename t,
typename tc>
30942 const tc *
const color,
const float opacity=1) {
30944 const CImg<t> &val = eig[0], &vec = eig[1];
30945 return draw_ellipse(x0,y0,std::sqrt(val(0)),std::sqrt(val(1)),
30946 std::atan2(vec(0,1),vec(0,0))*180/
cimg::PI,
30961 template<
typename tc>
30963 const tc *
const color,
const float opacity,
const unsigned int pattern) {
30964 if (pattern) _draw_ellipse(x0,y0,r1,r2,angle,color,opacity,pattern);
30977 template<
typename t,
typename tc>
30979 const tc *
const color,
const float opacity,
30980 const unsigned int pattern) {
30982 const CImg<t> &val = eig[0], &vec = eig[1];
30983 return draw_ellipse(x0,y0,std::sqrt(val(0)),std::sqrt(val(1)),
30984 std::atan2(vec(0,1),vec(0,0))*180/
cimg::PI,
30985 color,opacity,pattern);
30988 template<
typename tc>
30989 CImg<T>& _draw_ellipse(
const int x0,
const int y0,
const float r1,
const float r2,
const float angle,
30990 const tc *
const color,
const float opacity,
30991 const unsigned int pattern) {
30995 "draw_ellipse(): Specified color is (null).",
30997 if (r1<=0 || r2<=0)
return draw_point(x0,y0,color,opacity);
30998 _draw_scanline(color,opacity);
31001 nangle = (float)(angle*
cimg::PI/180),
31002 u = (float)std::cos(nangle),
31003 v = (float)std::sin(nangle),
31005 l1 = (float)std::pow(rmax/(nr1>0?nr1:1e-6),2),
31006 l2 = (
float)std::pow(rmax/(nr2>0?nr2:1e-6),2),
31007 a = l1*u*u + l2*v*v,
31009 c = l1*v*v + l2*u*u;
31011 yb = (int)std::sqrt(a*rmax*rmax/(a*c - b*b)),
31012 tymin = y0 - yb - 1,
31013 tymax = y0 + yb + 1,
31014 ymin = tymin<0?0:tymin,
31016 int oxmin = 0, oxmax = 0;
31017 bool first_line =
true;
31018 for (
int y = ymin; y<=ymax; ++y) {
31020 Y = y - y0 + (y<y0?0.5f:-0.5f),
31021 delta = b*b*Y*Y - a*(c*Y*Y - rmax*rmax),
31022 sdelta = delta>0?(float)std::sqrt(delta)/a:0.0f,
31024 fxmin = x0 - 0.5f - bY - sdelta,
31025 fxmax = x0 + 0.5f - bY + sdelta;
31026 const int xmin = (int)fxmin, xmax = (
int)fxmax;
31027 if (!pattern) _draw_scanline(xmin,xmax,y,color,opacity);
31030 if (y0-yb>=0) _draw_scanline(xmin,xmax,y,color,opacity);
31031 else draw_point(xmin,y,color,opacity).draw_point(xmax,y,color,opacity);
31032 first_line =
false;
31034 if (xmin<oxmin) _draw_scanline(xmin,oxmin-1,y,color,opacity);
31035 else _draw_scanline(oxmin+(oxmin==xmin?0:1),xmin,y,color,opacity);
31036 if (xmax<oxmax) _draw_scanline(xmax,oxmax-1,y,color,opacity);
31037 else _draw_scanline(oxmax+(oxmax==xmax?0:1),xmax,y,color,opacity);
31038 if (y==tymax) _draw_scanline(xmin+1,xmax-1,y,color,opacity);
31041 oxmin = xmin; oxmax = xmax;
31056 template<
typename tc>
31058 const tc *
const color,
const float opacity=1) {
31062 "draw_circle(): Specified color is (null).",
31064 _draw_scanline(color,opacity);
31065 if (radius<0 || x0-radius>=
width() || y0+radius<0 || y0-radius>=
height())
return *
this;
31066 if (y0>=0 && y0<
height()) _draw_scanline(x0-radius,x0+radius,y0,color,opacity);
31067 for (
int f = 1-radius, ddFx = 0, ddFy = -(radius<<1), x = 0, y = radius; x<y; ) {
31069 const int x1 = x0-x, x2 = x0+x, y1 = y0-y, y2 = y0+y;
31070 if (y1>=0 && y1<
height()) _draw_scanline(x1,x2,y1,color,opacity);
31071 if (y2>=0 && y2<
height()) _draw_scanline(x1,x2,y2,color,opacity);
31074 const bool no_diag = y!=(x++);
31076 const int x1 = x0-y, x2 = x0+y, y1 = y0-x, y2 = y0+x;
31078 if (y1>=0 && y1<
height()) _draw_scanline(x1,x2,y1,color,opacity);
31079 if (y2>=0 && y2<
height()) _draw_scanline(x1,x2,y2,color,opacity);
31094 template<
typename tc>
31096 const tc *
const color,
const float opacity,
31097 const unsigned int pattern) {
31102 "draw_circle(): Specified color is (null).",
31104 if (radius<0 || x0-radius>=
width() || y0+radius<0 || y0-radius>=
height())
return *
this;
31105 if (!radius)
return draw_point(x0,y0,color,opacity);
31106 draw_point(x0-radius,y0,color,opacity).draw_point(x0+radius,y0,color,opacity).
31107 draw_point(x0,y0-radius,color,opacity).draw_point(x0,y0+radius,color,opacity);
31108 if (radius==1)
return *
this;
31109 for (
int f = 1-radius, ddFx = 0, ddFy = -(radius<<1), x = 0, y = radius; x<y; ) {
31110 if (f>=0) { f+=(ddFy+=2); --y; }
31111 ++x; ++(f+=(ddFx+=2));
31113 const int x1 = x0-y, x2 = x0+y, y1 = y0-x, y2 = y0+x, x3 = x0-x, x4 = x0+x, y3 = y0-y, y4 = y0+y;
31114 draw_point(x1,y1,color,opacity).draw_point(x1,y2,color,opacity).
31115 draw_point(x2,y1,color,opacity).draw_point(x2,y2,color,opacity);
31117 draw_point(x3,y3,color,opacity).draw_point(x4,y4,color,opacity).
31118 draw_point(x4,y3,color,opacity).draw_point(x3,y4,color,opacity);
31133 template<
typename t>
31135 const CImg<t>& sprite,
const float opacity=1) {
31136 if (
is_empty() || !sprite)
return *
this;
31138 if (x0==0 && y0==0 && z0==0 && c0==0 &&
is_sameXYZC(sprite) && opacity>=1)
return assign(sprite,
false);
31139 const bool bx = (x0<0), by = (y0<0), bz = (z0<0), bc = (c0<0);
31141 lX = sprite.width() - (x0 + sprite.width()>
width()?x0 + sprite.width() -
width():0) + (bx?x0:0),
31142 lY = sprite.height() - (y0 + sprite.height()>
height()?y0 + sprite.height() -
height():0) + (by?y0:0),
31143 lZ = sprite.depth() - (z0 + sprite.depth()>
depth()?z0 + sprite.depth() -
depth():0) + (bz?z0:0),
31144 lC = sprite.spectrum() - (c0 + sprite.spectrum()>
spectrum()?c0 + sprite.spectrum() -
spectrum():0) + (bc?c0:0);
31146 *ptrs = sprite._data -
31148 (by?y0*sprite.width():0) -
31149 (bz?z0*sprite.width()*sprite.height():0) -
31150 (bc?c0*sprite.width()*sprite.height()*sprite.depth():0);
31151 const unsigned long
31152 offX = (
unsigned long)_width - lX,
31153 soffX = (
unsigned long)sprite._width - lX,
31154 offY = (
unsigned long)_width*(_height - lY),
31155 soffY = (
unsigned long)sprite._width*(sprite._height - lY),
31156 offZ = (
unsigned long)_width*_height*(_depth - lZ),
31157 soffZ = (
unsigned long)sprite._width*sprite._height*(sprite._depth - lZ);
31159 if (lX>0 && lY>0 && lZ>0 && lC>0) {
31160 T *ptrd =
data(x0<0?0:x0,y0<0?0:y0,z0<0?0:z0,c0<0?0:c0);
31161 for (
int v = 0; v<lC; ++v) {
31162 for (
int z = 0; z<lZ; ++z) {
31163 for (
int y = 0; y<lY; ++y) {
31164 if (opacity>=1)
for (
int x = 0; x<lX; ++x) *(ptrd++) = (T)*(ptrs++);
31165 else for (
int x = 0; x<lX; ++x) { *ptrd = (T)(nopacity*(*(ptrs++)) + *ptrd*copacity); ++ptrd; }
31166 ptrd+=offX; ptrs+=soffX;
31168 ptrd+=offY; ptrs+=soffY;
31170 ptrd+=offZ; ptrs+=soffZ;
31178 const CImg<T>& sprite,
const float opacity=1) {
31179 if (
is_empty() || !sprite)
return *
this;
31181 if (x0==0 && y0==0 && z0==0 && c0==0 &&
is_sameXYZC(sprite) && opacity>=1)
return assign(sprite,
false);
31182 const bool bx = (x0<0), by = (y0<0), bz = (z0<0), bc = (c0<0);
31184 lX = sprite.width() - (x0 + sprite.width()>
width()?x0 + sprite.width() -
width():0) + (bx?x0:0),
31185 lY = sprite.height() - (y0 + sprite.height()>
height()?y0 + sprite.height() -
height():0) + (by?y0:0),
31186 lZ = sprite.depth() - (z0 + sprite.depth()>
depth()?z0 + sprite.depth() -
depth():0) + (bz?z0:0),
31187 lC = sprite.spectrum() - (c0 + sprite.spectrum()>
spectrum()?c0 + sprite.spectrum() -
spectrum():0) + (bc?c0:0);
31189 *ptrs = sprite._data -
31191 (by?y0*sprite.width():0) -
31192 (bz?z0*sprite.width()*sprite.height():0) -
31193 (bc?c0*sprite.width()*sprite.height()*sprite.depth():0);
31194 const unsigned long
31195 offX = (
unsigned long)_width - lX,
31196 soffX = (
unsigned long)sprite._width - lX,
31197 offY = (
unsigned long)_width*(_height - lY),
31198 soffY = (
unsigned long)sprite._width*(sprite._height - lY),
31199 offZ = (
unsigned long)_width*_height*(_depth - lZ),
31200 soffZ = (
unsigned long)sprite._width*sprite._height*(sprite._depth - lZ),
31201 slX = lX*
sizeof(T);
31203 if (lX>0 && lY>0 && lZ>0 && lC>0) {
31204 T *ptrd =
data(x0<0?0:x0,y0<0?0:y0,z0<0?0:z0,c0<0?0:c0);
31205 for (
int v = 0; v<lC; ++v) {
31206 for (
int z = 0; z<lZ; ++z) {
31207 if (opacity>=1)
for (
int y = 0; y<lY; ++y) { std::memcpy(ptrd,ptrs,slX); ptrd+=_width; ptrs+=sprite._width; }
31208 else for (
int y = 0; y<lY; ++y) {
31209 for (
int x = 0; x<lX; ++x) { *ptrd = (T)(nopacity*(*(ptrs++)) + *ptrd*copacity); ++ptrd; }
31210 ptrd+=offX; ptrs+=soffX;
31212 ptrd+=offY; ptrs+=soffY;
31214 ptrd+=offZ; ptrs+=soffZ;
31221 template<
typename t>
31223 const CImg<t>& sprite,
const float opacity=1) {
31224 return draw_image(x0,y0,z0,0,sprite,opacity);
31228 template<
typename t>
31230 const CImg<t>& sprite,
const float opacity=1) {
31235 template<
typename t>
31237 const CImg<t>& sprite,
const float opacity=1) {
31242 template<
typename t>
31261 template<
typename ti,
typename tm>
31264 const float mask_max_value=1) {
31265 if (
is_empty() || !sprite || !mask)
return *
this;
31268 if (mask._width!=sprite._width || mask._height!=sprite._height || mask._depth!=sprite._depth)
31270 "draw_image(): Sprite (%u,%u,%u,%u,%p) and mask (%u,%u,%u,%u,%p) have incompatible dimensions.",
31272 sprite._width,sprite._height,sprite._depth,sprite._spectrum,sprite._data,
31273 mask._width,mask._height,mask._depth,mask._spectrum,mask._data);
31275 const bool bx = (x0<0), by = (y0<0), bz = (z0<0), bc = (c0<0);
31277 lX = sprite.width() - (x0 + sprite.width()>
width()?x0 + sprite.width() -
width():0) + (bx?x0:0),
31278 lY = sprite.height() - (y0 + sprite.height()>
height()?y0 + sprite.height() -
height():0) + (by?y0:0),
31279 lZ = sprite.depth() - (z0 + sprite.depth()>
depth()?z0 + sprite.depth() -
depth():0) + (bz?z0:0),
31280 lC = sprite.spectrum() - (c0 + sprite.spectrum()>
spectrum()?c0 + sprite.spectrum() -
spectrum():0) + (bc?c0:0);
31282 coff = -(bx?x0:0)-(by?y0*mask.width():0)-(bz?z0*mask.width()*mask.height():0)-(bc?c0*mask.width()*mask.height()*mask.depth():0),
31283 ssize = mask.width()*mask.height()*mask.depth();
31284 const ti *ptrs = sprite._data + coff;
31285 const tm *ptrm = mask._data + coff;
31286 const unsigned long
31287 offX = (
unsigned long)_width - lX,
31288 soffX = (
unsigned long)sprite._width - lX,
31289 offY = (
unsigned long)_width*(_height - lY),
31290 soffY = (
unsigned long)sprite._width*(sprite._height - lY),
31291 offZ = (
unsigned long)_width*_height*(_depth - lZ),
31292 soffZ = (
unsigned long)sprite._width*sprite._height*(sprite._depth - lZ);
31293 if (lX>0 && lY>0 && lZ>0 && lC>0) {
31294 T *ptrd =
data(x0<0?0:x0,y0<0?0:y0,z0<0?0:z0,c0<0?0:c0);
31295 for (
int c = 0; c<lC; ++c) {
31296 ptrm = mask._data + (ptrm - mask._data)%ssize;
31297 for (
int z = 0; z<lZ; ++z) {
31298 for (
int y = 0; y<lY; ++y) {
31299 for (
int x = 0; x<lX; ++x) {
31300 const float mopacity = (float)(*(ptrm++)*opacity),
31302 *ptrd = (T)((nopacity*(*(ptrs++)) + *ptrd*copacity)/mask_max_value);
31305 ptrd+=offX; ptrs+=soffX; ptrm+=soffX;
31307 ptrd+=offY; ptrs+=soffY; ptrm+=soffY;
31309 ptrd+=offZ; ptrs+=soffZ; ptrm+=soffZ;
31316 template<
typename ti,
typename tm>
31319 const float mask_max_value=1) {
31320 return draw_image(x0,y0,z0,0,sprite,mask,opacity,mask_max_value);
31324 template<
typename ti,
typename tm>
31327 const float mask_max_value=1) {
31328 return draw_image(x0,y0,0,sprite,mask,opacity,mask_max_value);
31332 template<
typename ti,
typename tm>
31335 const float mask_max_value=1) {
31336 return draw_image(x0,0,sprite,mask,opacity,mask_max_value);
31340 template<
typename ti,
typename tm>
31342 const float mask_max_value=1) {
31343 return draw_image(0,sprite,mask,opacity,mask_max_value);
31356 template<
typename tc1,
typename tc2,
typename t>
31358 const char *
const text,
31359 const tc1 *
const foreground_color,
const tc2 *
const background_color,
31360 const float opacity,
const CImgList<t>& font, ...) {
31361 if (!font)
return *
this;
31362 char tmp[2048] = { 0 }; std::va_list ap; va_start(ap,font);
31363 cimg_vsnprintf(tmp,
sizeof(tmp),text,ap); va_end(ap);
31364 return _draw_text(x0,y0,tmp,foreground_color,background_color,opacity,font);
31371 template<
typename tc,
typename t>
31373 const char *
const text,
31374 const tc *
const foreground_color,
const int,
31375 const float opacity,
const CImgList<t>& font, ...) {
31376 if (!font)
return *
this;
31377 char tmp[2048] = { 0 }; std::va_list ap; va_start(ap,font);
31378 cimg_vsnprintf(tmp,
sizeof(tmp),text,ap); va_end(ap);
31379 return _draw_text(x0,y0,tmp,foreground_color,(tc*)0,opacity,font);
31386 template<
typename tc,
typename t>
31388 const char *
const text,
31389 const int,
const tc *
const background_color,
31390 const float opacity,
const CImgList<t>& font, ...) {
31391 if (!font)
return *
this;
31392 char tmp[2048] = { 0 }; std::va_list ap; va_start(ap,font);
31393 cimg_vsnprintf(tmp,
sizeof(tmp),text,ap); va_end(ap);
31394 return _draw_text(x0,y0,tmp,(tc*)0,background_color,opacity,font);
31407 template<
typename tc1,
typename tc2>
31409 const char *
const text,
31410 const tc1 *
const foreground_color,
const tc2 *
const background_color,
31411 const float opacity=1,
const unsigned int font_height=13, ...) {
31412 if (!font_height)
return *
this;
31413 char tmp[2048] = { 0 }; std::va_list ap; va_start(ap,font_height); cimg_vsnprintf(tmp,
sizeof(tmp),text,ap); va_end(ap);
31416 ref_height = font_height<=13?13:font_height<=28?24:font_height<=32?32:57,
31417 padding_x = font_height<=18?1:font_height<=32?2:3;
31418 if (!font || font[0]._height!=font_height) {
31420 font[0].
assign(1,font_height);
31421 if (ref_height==font_height) cimglist_for(font,l) font[l].resize(font[l]._width + padding_x,-100,-100,-100,0);
31424 if (font[0]._spectrum!=1) cimglist_for_in(font,0,255,l) font[l].channel(0);
31425 }
else if (font[0]._spectrum<_spectrum) cimglist_for_in(font,0,255,l) font[l].resize(-100,-100,1,_spectrum);
31426 if (ref_height!=font_height)
for (
const char *ptrs = tmp; *ptrs; ++ptrs) {
31427 const unsigned int __c = (
unsigned int)(
unsigned char)*ptrs, _c = (__c==
'\t')?
' ':__c;
31428 if (_c<font._width) {
31430 if (c._height!=font_height) {
31431 c.
resize(
cimg::max(1U,c._width*font_height/c._height),font_height,-100,-100,c._height>font_height?2:3);
31432 c.
resize(c._width + padding_x,-100,-100,-100,0);
31435 if (_c+256U<font._width) {
31437 if (c._height!=font_height) {
31438 c.
resize(
cimg::max(1U,c._width*font_height/c._height),font_height,-100,-100,c._height>font_height?2:3);
31439 c.
resize(c._width + padding_x,-100,-100,-100,0);
31443 return _draw_text(x0,y0,tmp,foreground_color,background_color,opacity,font);
31447 template<
typename tc>
31449 const char *
const text,
31450 const tc *
const foreground_color,
const int background_color=0,
31451 const float opacity=1,
const unsigned int font_height=13, ...) {
31452 if (!font_height)
return *
this;
31454 char tmp[2048] = { 0 }; std::va_list ap; va_start(ap,font_height); cimg_vsnprintf(tmp,
sizeof(tmp),text,ap); va_end(ap);
31455 return draw_text(x0,y0,
"%s",foreground_color,(
const tc*)0,opacity,font_height,tmp);
31459 template<
typename tc>
31461 const char *
const text,
31462 const int,
const tc *
const background_color,
31463 const float opacity=1,
const unsigned int font_height=13, ...) {
31464 if (!font_height)
return *
this;
31465 char tmp[2048] = { 0 }; std::va_list ap; va_start(ap,font_height); cimg_vsnprintf(tmp,
sizeof(tmp),text,ap); va_end(ap);
31466 return draw_text(x0,y0,
"%s",(tc*)0,background_color,opacity,font_height,tmp);
31469 template<
typename tc1,
typename tc2,
typename t>
31470 CImg<T>& _draw_text(
const int x0,
const int y0,
31471 const char *
const text,
31472 const tc1 *
const foreground_color,
const tc2 *
const background_color,
31474 if (!text)
return *
this;
31477 "draw_text(): Empty specified font.",
31479 const unsigned int text_length = (
unsigned int)std::strlen(text);
31482 int x = 0, y = 0, w = 0;
31483 unsigned char c = 0;
31484 for (
unsigned int i = 0; i<text_length; ++i) {
31487 case '\n' : y+=font[0]._height;
if (x>w) w = x; x = 0;
break;
31488 case '\t' : x+=4*font[
' ']._width;
break;
31489 default :
if (c<font._width) x+=font[c]._width;
31492 if (x!=0 || c==
'\n') {
31494 y+=font[0]._height;
31496 assign(x0+w,y0+y,1,font[0]._spectrum,0);
31500 int x = x0, y = y0;
31502 for (
unsigned int i = 0; i<text_length; ++i) {
31503 const unsigned char c = text[i];
31505 case '\n' : y+=font[
' ']._height; x = x0;
break;
31506 case '\t' : x+=4*font[
' ']._width;
break;
31507 default :
if (c<font._width) {
31509 const unsigned int cmin =
cimg::min(_spectrum,letter._spectrum);
31510 const CImg<t>& mask = (c+256)<(
int)font._width?font[c+256]:font[c];
31511 if (foreground_color)
31512 for (
unsigned long p = 0; p<(
unsigned long)letter._width*letter._height; ++p)
31513 if (mask(p))
for (
unsigned int c = 0; c<cmin; ++c) letter(p,0,0,c) = (t)(letter(p,0,0,c)*foreground_color[c]);
31514 if (background_color)
31515 for (
unsigned long p = 0; p<(
unsigned long)letter._width*letter._height; ++p)
31516 if (!mask(p))
for (
unsigned int c = 0; c<cmin; ++c) letter(p,0,0,c) = (t)background_color[c];
31517 if (!background_color && font._width>=512)
draw_image(x,y,letter,mask,opacity,(T)1);
31537 template<
typename t1,
typename t2>
31539 const t2 *
const color,
const float opacity=1,
31540 const unsigned int sampling=25,
const float factor=-20,
31541 const bool is_arrow=
true,
const unsigned int pattern=~0U) {
31542 return draw_quiver(flow,
CImg<t2>(color,_spectrum,1,1,1,
true),opacity,sampling,factor,is_arrow,pattern);
31556 template<
typename t1,
typename t2>
31558 const CImg<t2>& color,
const float opacity=1,
31559 const unsigned int sampling=25,
const float factor=-20,
31560 const bool is_arrow=
true,
const unsigned int pattern=~0U) {
31562 if (!flow || flow._spectrum!=2)
31564 "draw_quiver(): Invalid dimensions of specified flow (%u,%u,%u,%u,%p).",
31566 flow._width,flow._height,flow._depth,flow._spectrum,flow._data);
31569 "draw_quiver(): Invalid sampling value %g "
31573 const bool colorfield = (color._width==flow._width && color._height==flow._height && color._depth==1 && color._spectrum==_spectrum);
31577 float m, M = (float)flow.get_norm(2).max_min(m);
31579 if (!vmax) vmax = 1;
31581 }
else { fact = factor; vmax = 1; }
31583 for (
unsigned int y = sampling/2; y<_height; y+=sampling)
31584 for (
unsigned int x = sampling/2; x<_width; x+=sampling) {
31585 const unsigned int X = x*flow._width/_width, Y = y*flow._height/_height;
31586 float u = (float)flow(X,Y,0,0)*fact/vmax, v = (float)flow(X,Y,0,1)*fact/vmax;
31588 const int xx = x+(int)u, yy = y+(
int)v;
31589 if (colorfield)
draw_arrow(x,y,xx,yy,color.get_vector_at(X,Y)._data,opacity,45,sampling/5.0f,pattern);
31590 else draw_arrow(x,y,xx,yy,color._data,opacity,45,sampling/5.0f,pattern);
31592 if (colorfield)
draw_line((
int)(x-0.5*u),(
int)(y-0.5*v),(
int)(x+0.5*u),(
int)(y+0.5*v),color.get_vector_at(X,Y)._data,opacity,pattern);
31593 else draw_line((
int)(x-0.5*u),(
int)(y-0.5*v),(
int)(x+0.5*u),(
int)(y+0.5*v),color._data,opacity,pattern);
31610 template<
typename t,
typename tc>
31612 const tc *
const color,
const float opacity=1,
31613 const unsigned int pattern=~0U,
const unsigned int font_height=13,
31614 const bool allow_zero=
true) {
31616 const int yt = (y+3+font_height)<_height?(y+3):(y-2-font_height);
31617 const int siz = (int)values_x.size()-1;
31618 char txt[32] = { 0 };
31621 draw_line(0,y,_width-1,y,color,opacity,pattern);
31623 cimg_snprintf(txt,
sizeof(txt),
"%g",(
double)*values_x);
31624 label.assign().draw_text(0,0,txt,color,(tc*)0,opacity,font_height);
31626 _xt = (
width() - label.width())/2,
31627 xt = _xt<3?3:_xt+label.width()>=
width()-2?
width()-3-label.width():_xt;
31629 if (allow_zero || txt[0]!=
'0' || txt[1]!=0)
31630 draw_text(xt,yt,txt,color,(tc*)0,opacity,font_height);
31633 if (values_x[0]<values_x[siz])
draw_arrow(0,y,_width-1,y,color,opacity,30,5,pattern);
31634 else draw_arrow(_width-1,y,0,y,color,opacity,30,5,pattern);
31635 cimg_foroff(values_x,x) {
31636 cimg_snprintf(txt,
sizeof(txt),
"%g",(
double)values_x(x));
31637 label.assign().draw_text(0,0,txt,color,(tc*)0,opacity,font_height);
31639 xi = (int)(x*(_width-1)/siz),
31640 _xt = xi - label.width()/2,
31641 xt = _xt<3?3:_xt+label.width()>=
width()-2?
width()-3-label.width():_xt;
31642 draw_point(xi,y-1,color,opacity).draw_point(xi,y+1,color,opacity);
31643 if (allow_zero || txt[0]!=
'0' || txt[1]!=0)
31644 draw_text(xt,yt,txt,color,(tc*)0,opacity,font_height);
31660 template<
typename t,
typename tc>
31662 const tc *
const color,
const float opacity=1,
31663 const unsigned int pattern=~0U,
const unsigned int font_height=13,
31664 const bool allow_zero=
true) {
31666 int siz = (int)values_y.size()-1;
31667 char txt[32] = { 0 };
31670 draw_line(x,0,x,_height-1,color,opacity,pattern);
31672 cimg_snprintf(txt,
sizeof(txt),
"%g",(
double)*values_y);
31673 label.assign().draw_text(0,0,txt,color,(tc*)0,opacity,font_height);
31675 _yt = (
height() - label.height())/2,
31676 yt = _yt<0?0:_yt+label.height()>=
height()?
height()-1-label.height():_yt,
31677 _xt = x - 2 - label.width(),
31678 xt = _xt>=0?_xt:x+3;
31680 if (allow_zero || txt[0]!=
'0' || txt[1]!=0)
31681 draw_text(xt,yt,txt,color,(tc*)0,opacity,font_height);
31684 if (values_y[0]<values_y[siz])
draw_arrow(x,0,x,_height-1,color,opacity,30,5,pattern);
31685 else draw_arrow(x,_height-1,x,0,color,opacity,30,5,pattern);
31686 cimg_foroff(values_y,y) {
31687 cimg_snprintf(txt,
sizeof(txt),
"%g",(
double)values_y(y));
31688 label.assign().draw_text(0,0,txt,color,(tc*)0,opacity,font_height);
31690 yi = (int)(y*(_height-1)/siz),
31691 _yt = yi - label.height()/2,
31692 yt = _yt<0?0:_yt+label.height()>=
height()?
height()-1-label.height():_yt,
31693 _xt = x - 2 - label.width(),
31694 xt = _xt>=0?_xt:x+3;
31695 draw_point(x-1,yi,color,opacity).draw_point(x+1,yi,color,opacity);
31696 if (allow_zero || txt[0]!=
'0' || txt[1]!=0)
31697 draw_text(xt,yt,txt,color,(tc*)0,opacity,font_height);
31714 template<
typename tx,
typename ty,
typename tc>
31716 const tc *
const color,
const float opacity=1,
31717 const unsigned int pattern_x=~0U,
const unsigned int pattern_y=~0U,
31718 const unsigned int font_height=13,
const bool allow_zero=
true) {
31720 const CImg<tx> nvalues_x(values_x._data,values_x.size(),1,1,1,
true);
31721 const int sizx = (int)values_x.size()-1, wm1 =
width()-1;
31723 float ox = (float)*nvalues_x;
31724 for (
unsigned int x = sizx?1:0; x<_width; ++x) {
31725 const float nx = (float)nvalues_x._linear_atX((
float)x*sizx/wm1);
31726 if (nx*ox<=0) {
draw_axis(nx==0?x:x-1,values_y,color,opacity,pattern_y,font_height,allow_zero);
break; }
31730 const CImg<ty> nvalues_y(values_y._data,values_y.size(),1,1,1,
true);
31731 const int sizy = (int)values_y.size()-1, hm1 =
height()-1;
31733 float oy = (float)nvalues_y[0];
31734 for (
unsigned int y = sizy?1:0; y<_height; ++y) {
31735 const float ny = (float)nvalues_y._linear_atX((
float)y*sizy/hm1);
31736 if (ny*oy<=0) {
draw_axis(values_x,ny==0?y:y-1,color,opacity,pattern_x,font_height,allow_zero);
break; }
31744 template<
typename tc>
31746 const tc *
const color,
const float opacity=1,
31747 const int subdivisionx=-60,
const int subdivisiony=-60,
31748 const float precisionx=0,
const float precisiony=0,
31749 const unsigned int pattern_x=~0U,
const unsigned int pattern_y=~0U,
31750 const unsigned int font_height=13) {
31752 const bool allow_zero = (x0*x1>0) || (y0*y1>0);
31755 px = dx<=0?1:precisionx==0?(float)std::pow(10.0,(
int)std::log10(dx)-2.0):precisionx,
31756 py = dy<=0?1:precisiony==0?(float)std::pow(10.0,(
int)std::log10(dy)-2.0):precisiony;
31757 if (x0!=x1 && y0!=y1)
31760 color,opacity,pattern_x,pattern_y,font_height,allow_zero);
31761 else if (x0==x1 && y0!=y1)
31763 color,opacity,pattern_y,font_height);
31764 else if (x0!=x1 && y0==y1)
31766 color,opacity,pattern_x,font_height);
31779 template<
typename tx,
typename ty,
typename tc>
31781 const tc *
const color,
const float opacity=1,
31782 const unsigned int pattern_x=~0U,
const unsigned int pattern_y=~0U) {
31784 if (values_x) cimg_foroff(values_x,x) {
31785 const int xi = (int)values_x[x];
31786 if (xi>=0 && xi<
width())
draw_line(xi,0,xi,_height-1,color,opacity,pattern_x);
31788 if (values_y) cimg_foroff(values_y,y) {
31789 const int yi = (int)values_y[y];
31790 if (yi>=0 && yi<
height())
draw_line(0,yi,_width-1,yi,color,opacity,pattern_y);
31796 template<
typename tc>
31798 const float offsetx,
const float offsety,
31799 const bool invertx,
const bool inverty,
31800 const tc *
const color,
const float opacity=1,
31801 const unsigned int pattern_x=~0U,
const unsigned int pattern_y=~0U) {
31805 const float dx = delta_x>0?delta_x:_width*-delta_x/100;
31806 const unsigned int nx = (
unsigned int)(_width/dx);
31808 if (offsetx) cimg_foroff(seqx,x) seqx(x) = (
unsigned int)
cimg::mod(seqx(x)+offsetx,(float)_width);
31809 if (invertx) cimg_foroff(seqx,x) seqx(x) = _width - 1 - seqx(x);
31812 const float dy = delta_y>0?delta_y:_height*-delta_y/100;
31813 const unsigned int ny = (
unsigned int)(_height/dy);
31815 if (offsety) cimg_foroff(seqy,y) seqy(y) = (
unsigned int)
cimg::mod(seqy(y)+offsety,(float)_height);
31816 if (inverty) cimg_foroff(seqy,y) seqy(y) = _height - 1 - seqy(y);
31818 return draw_grid(seqx,seqy,color,opacity,pattern_x,pattern_y);
31847 template<
typename t,
typename tc>
31849 const tc *
const color,
const float opacity=1,
31850 const unsigned int plot_type=1,
const int vertex_type=1,
31851 const double ymin=0,
const double ymax=0,
const unsigned int pattern=~0U) {
31852 if (
is_empty() || _height<=1)
return *
this;
31855 "draw_graph(): Specified color is (null).",
31860 if (plot_type==3) {
31861 color1.assign(_spectrum); color2.assign(_spectrum);
31866 const unsigned long
31868 _siz1 = siz - (plot_type!=3?1:0),
31869 siz1 = _siz1?_siz1:1;
31871 _width1 = _width - (plot_type!=3?1:0),
31872 width1 = _width1?_width1:1;
31873 double m = ymin, M = ymax;
31874 if (ymin==ymax) m = (double)data.max_min(M);
31875 if (m==M) { --m; ++M; }
31876 const float ca = (float)(M-m)/(_height-1);
31877 bool init_hatch =
true;
31880 switch (plot_type%4) {
31882 int oX = 0, oY = (int)((data[0]-m)/ca);
31884 const int Y = (int)((*data-m)/ca);
31886 }
else for (
unsigned long off = 1; off<siz; ++off) {
31888 X = off*_width1/siz1,
31889 Y = (int)((data[off]-m)/ca);
31890 draw_line(oX,oY,X,Y,color,opacity,pattern,init_hatch);
31892 init_hatch =
false;
31896 const CImg<t> ndata(data._data,siz,1,1,1,
true);
31897 int oY = (int)((data[0]-m)/ca);
31898 cimg_forX(*
this,x) {
31899 const int Y = (int)((ndata._cubic_atX((
float)x*siz1/width1)-m)/ca);
31900 if (x>0)
draw_line(x,oY,x+1,Y,color,opacity,pattern,init_hatch);
31901 init_hatch =
false;
31906 const int Y0 = (int)(-m/ca);
31908 cimg_foroff(data,off) {
31910 X = (off+1)*_width/siz-1,
31911 Y = (
int)((data[off]-m)/ca);
31913 draw_line(oX,Y,oX,Y0,color2.data(),opacity).
31914 draw_line(oX,Y0,X,Y0,Y<=Y0?color2.data():color1.data(),opacity).
31915 draw_line(X,Y,X,Y0,color1.data(),opacity).
31916 draw_line(oX,Y,X,Y,Y<=Y0?color1.data():color2.data(),opacity);
31924 const unsigned int wb2 = plot_type==3?_width1/(2*siz):0;
31925 switch (vertex_type%8) {
31927 cimg_foroff(data,off) {
31929 X = off*_width1/siz1 + wb2,
31930 Y = (int)((data[off]-m)/ca);
31935 cimg_foroff(data,off) {
31937 X = off*_width1/siz1 + wb2,
31938 Y = (int)((data[off]-m)/ca);
31939 draw_line(X-3,Y,X+3,Y,color,opacity).draw_line(X,Y-3,X,Y+3,color,opacity);
31943 cimg_foroff(data,off) {
31945 X = off*_width1/siz1 + wb2,
31946 Y = (int)((data[off]-m)/ca);
31947 draw_line(X-3,Y-3,X+3,Y+3,color,opacity).draw_line(X-3,Y+3,X+3,Y-3,color,opacity);
31951 cimg_foroff(data,off) {
31953 X = off*_width1/siz1 + wb2,
31954 Y = (int)((data[off]-m)/ca);
31959 cimg_foroff(data,off) {
31961 X = off*_width1/siz1 + wb2,
31962 Y = (int)((data[off]-m)/ca);
31967 cimg_foroff(data,off) {
31969 X = off*_width1/siz1 + wb2,
31970 Y = (int)((data[off]-m)/ca);
31975 cimg_foroff(data,off) {
31977 X = off*_width1/siz1 + wb2,
31978 Y = (int)((data[off]-m)/ca);
32002 template<
typename tc,
typename t>
32004 const tc *
const color,
const float opacity,
32005 CImg<t>& region,
const float sigma=0,
32006 const bool is_high_connexity=
false) {
32008 #define _cimg_draw_fill_test(x,y,z,res) if (region(x,y,z)) res = false; else { \
32010 const T *reference_col = reference_color._data + _spectrum, *ptrs = data(x,y,z) + siz; \
32011 for (unsigned int i = _spectrum; res && i; --i) { ptrs-=whd; res = (cimg::abs(*ptrs - *(--reference_col))<=sigma); } \
32012 region(x,y,z) = (t)(res?1:noregion); \
32015 #define _cimg_draw_fill_set(x,y,z) { \
32016 const tc *col = color; \
32017 T *ptrd = data(x,y,z); \
32018 if (opacity>=1) cimg_forC(*this,c) { *ptrd = (T)*(col++); ptrd+=whd; } \
32019 else cimg_forC(*this,c) { *ptrd = (T)(*(col++)*nopacity + *ptrd*copacity); ptrd+=whd; } \
32022 #define _cimg_draw_fill_insert(x,y,z) { \
32023 if (posr1>=remaining._height) remaining.resize(3,remaining._height<<1,1,1,0); \
32024 unsigned int *ptrr = remaining.data(0,posr1); \
32025 *(ptrr++) = x; *(ptrr++) = y; *(ptrr++) = z; ++posr1; \
32028 #define _cimg_draw_fill_test_neighbor(x,y,z,cond) if (cond) { \
32029 const unsigned int tx = x, ty = y, tz = z; \
32030 _cimg_draw_fill_test(tx,ty,tz,res); if (res) _cimg_draw_fill_insert(tx,ty,tz); \
32035 "draw_fill(): Specified color is (null).",
32038 region.assign(_width,_height,_depth,1,(t)0);
32041 const unsigned long whd = (
unsigned long)_width*_height*_depth, siz = (
unsigned long)_spectrum*whd;
32042 const unsigned int W1 = _width-1, H1 = _height-1, D1 = _depth-1;
32043 const bool is_3d = (_depth>1);
32046 remaining(0,0) = x; remaining(1,0) = y; remaining(2,0) = z;
32047 unsigned int posr0 = 0, posr1 = 1;
32048 region(x,y,z) = (t)1;
32049 const t noregion = ((t)1==(t)2)?(t)0:(t)(-1);
32051 const unsigned int *pcurr = remaining.
data(0,posr0++), xc = *(pcurr++), yc = *(pcurr++), zc = *(pcurr++);
32052 if (posr0>=512) { remaining.
shift(0,-(
int)posr0); posr1-=posr0; posr0 = 0; }
32054 unsigned int nxc = xc;
32056 _cimg_draw_fill_set(nxc,yc,zc);
32057 _cimg_draw_fill_test_neighbor(nxc,yc-1,zc,yc!=0);
32058 _cimg_draw_fill_test_neighbor(nxc,yc+1,zc,yc<H1);
32059 _cimg_draw_fill_test_neighbor(nxc,yc,zc-1,zc!=0);
32060 _cimg_draw_fill_test_neighbor(nxc,yc,zc+1,zc<D1);
32061 if (nxc) { --nxc; _cimg_draw_fill_test(nxc,yc,zc,cont); }
else cont =
false;
32065 if ((++nxc)<=W1) { _cimg_draw_fill_test(nxc,yc,zc,cont); }
else cont =
false;
32067 _cimg_draw_fill_set(nxc,yc,zc);
32068 _cimg_draw_fill_test_neighbor(nxc,yc-1,zc,yc!=0);
32069 _cimg_draw_fill_test_neighbor(nxc,yc+1,zc,yc<H1);
32070 _cimg_draw_fill_test_neighbor(nxc,yc,zc-1,zc!=0);
32071 _cimg_draw_fill_test_neighbor(nxc,yc,zc+1,zc<D1);
32074 unsigned int nyc = yc;
32076 if (nyc) { --nyc; _cimg_draw_fill_test(xc,nyc,zc,cont); }
else cont =
false;
32078 _cimg_draw_fill_set(xc,nyc,zc);
32079 _cimg_draw_fill_test_neighbor(xc-1,nyc,zc,xc!=0);
32080 _cimg_draw_fill_test_neighbor(xc+1,nyc,zc,xc<W1);
32081 _cimg_draw_fill_test_neighbor(xc,nyc,zc-1,zc!=0);
32082 _cimg_draw_fill_test_neighbor(xc,nyc,zc+1,zc<D1);
32087 if ((++nyc)<=H1) { _cimg_draw_fill_test(xc,nyc,zc,cont); }
else cont =
false;
32089 _cimg_draw_fill_set(xc,nyc,zc);
32090 _cimg_draw_fill_test_neighbor(xc-1,nyc,zc,xc!=0);
32091 _cimg_draw_fill_test_neighbor(xc+1,nyc,zc,xc<W1);
32092 _cimg_draw_fill_test_neighbor(xc,nyc,zc-1,zc!=0);
32093 _cimg_draw_fill_test_neighbor(xc,nyc,zc+1,zc<D1);
32096 unsigned int nzc = zc;
32098 if (nzc) { --nzc; _cimg_draw_fill_test(xc,yc,nzc,cont); }
else cont =
false;
32100 _cimg_draw_fill_set(xc,yc,nzc);
32101 _cimg_draw_fill_test_neighbor(xc-1,yc,nzc,xc!=0);
32102 _cimg_draw_fill_test_neighbor(xc+1,yc,nzc,xc<W1);
32103 _cimg_draw_fill_test_neighbor(xc,yc-1,nzc,yc!=0);
32104 _cimg_draw_fill_test_neighbor(xc,yc+1,nzc,yc<H1);
32109 if ((++nzc)<=D1) { _cimg_draw_fill_test(xc,yc,nzc,cont); }
else cont =
false;
32111 _cimg_draw_fill_set(xc,nyc,zc);
32112 _cimg_draw_fill_test_neighbor(xc-1,yc,nzc,xc!=0);
32113 _cimg_draw_fill_test_neighbor(xc+1,yc,nzc,xc<W1);
32114 _cimg_draw_fill_test_neighbor(xc,yc-1,nzc,yc!=0);
32115 _cimg_draw_fill_test_neighbor(xc,yc+1,nzc,yc<H1);
32118 }
while (posr1>posr0);
32120 const unsigned int *pcurr = remaining.
data(0,posr0++), xc = *(pcurr++), yc = *(pcurr++);
32121 if (posr0>=512) { remaining.
shift(0,-(
int)posr0); posr1-=posr0; posr0 = 0; }
32123 unsigned int nxc = xc;
32125 _cimg_draw_fill_set(nxc,yc,0);
32126 _cimg_draw_fill_test_neighbor(nxc,yc-1,0,yc!=0);
32127 _cimg_draw_fill_test_neighbor(nxc,yc+1,0,yc<H1);
32128 if (is_high_connexity) {
32129 _cimg_draw_fill_test_neighbor(nxc-1,yc-1,0,(nxc!=0 && yc!=0));
32130 _cimg_draw_fill_test_neighbor(nxc+1,yc-1,0,(nxc<W1 && yc!=0));
32131 _cimg_draw_fill_test_neighbor(nxc-1,yc+1,0,(nxc!=0 && yc<H1));
32132 _cimg_draw_fill_test_neighbor(nxc+1,yc+1,0,(nxc<W1 && yc<H1));
32134 if (nxc) { --nxc; _cimg_draw_fill_test(nxc,yc,0,cont); }
else cont =
false;
32138 if ((++nxc)<=W1) { _cimg_draw_fill_test(nxc,yc,0,cont); }
else cont =
false;
32140 _cimg_draw_fill_set(nxc,yc,0);
32141 _cimg_draw_fill_test_neighbor(nxc,yc-1,0,yc!=0);
32142 _cimg_draw_fill_test_neighbor(nxc,yc+1,0,yc<H1);
32143 if (is_high_connexity) {
32144 _cimg_draw_fill_test_neighbor(nxc-1,yc-1,0,(nxc!=0 && yc!=0));
32145 _cimg_draw_fill_test_neighbor(nxc+1,yc-1,0,(nxc<W1 && yc!=0));
32146 _cimg_draw_fill_test_neighbor(nxc-1,yc+1,0,(nxc!=0 && yc<H1));
32147 _cimg_draw_fill_test_neighbor(nxc+1,yc+1,0,(nxc<W1 && yc<H1));
32151 unsigned int nyc = yc;
32153 if (nyc) { --nyc; _cimg_draw_fill_test(xc,nyc,0,cont); }
else cont =
false;
32155 _cimg_draw_fill_set(xc,nyc,0);
32156 _cimg_draw_fill_test_neighbor(xc-1,nyc,0,xc!=0);
32157 _cimg_draw_fill_test_neighbor(xc+1,nyc,0,xc<W1);
32158 if (is_high_connexity) {
32159 _cimg_draw_fill_test_neighbor(xc-1,nyc-1,0,(xc!=0 && nyc!=0));
32160 _cimg_draw_fill_test_neighbor(xc+1,nyc-1,0,(xc<W1 && nyc!=0));
32161 _cimg_draw_fill_test_neighbor(xc-1,nyc+1,0,(xc!=0 && nyc<H1));
32162 _cimg_draw_fill_test_neighbor(xc+1,nyc+1,0,(xc<W1 && nyc<H1));
32168 if ((++nyc)<=H1) { _cimg_draw_fill_test(xc,nyc,0,cont); }
else cont =
false;
32170 _cimg_draw_fill_set(xc,nyc,0);
32171 _cimg_draw_fill_test_neighbor(xc-1,nyc,0,xc!=0);
32172 _cimg_draw_fill_test_neighbor(xc+1,nyc,0,xc<W1);
32173 if (is_high_connexity) {
32174 _cimg_draw_fill_test_neighbor(xc-1,nyc-1,0,(xc!=0 && nyc!=0));
32175 _cimg_draw_fill_test_neighbor(xc+1,nyc-1,0,(xc<W1 && nyc!=0));
32176 _cimg_draw_fill_test_neighbor(xc-1,nyc+1,0,(xc!=0 && nyc<H1));
32177 _cimg_draw_fill_test_neighbor(xc+1,nyc+1,0,(xc<W1 && nyc<H1));
32181 }
while (posr1>posr0);
32182 if (noregion) cimg_for(region,ptrd,t)
if (*ptrd==noregion) *ptrd = (t)0;
32188 template<
typename tc>
32190 const tc *
const color,
const float opacity=1,
32191 const float sigma=0,
const bool is_high_connexity=
false) {
32193 return draw_fill(x,y,z,color,opacity,tmp,sigma,is_high_connexity);
32197 template<
typename tc>
32199 const tc *
const color,
const float opacity=1,
32200 const float sigma=0,
const bool is_high_connexity=
false) {
32202 return draw_fill(x,y,0,color,opacity,tmp,sigma,is_high_connexity);
32216 cimg_forZC(*
this,z,c) {
32218 for (
int d=1<<
cimg::min(scale,31U); d>1; d>>=1) {
32219 const int d2 = d>>1;
32220 const float r = alpha*d + beta;
32221 for (
int y0=0; y0<h; y0+=d)
32222 for (
int x0=0; x0<w; x0+=d) {
32223 const int x1 = (x0 + d)%w, y1 = (y0 + d)%h, xc = (x0 + d2)%w, yc = (y0 + d2)%h;
32224 const Tfloat val = (Tfloat)(0.25f*(ref(x0,y0) + ref(x0,y1) + ref(x0,y1) + ref(x1,y1)) + r*
cimg::crand());
32225 ref(xc,yc) = (T)(val<m?m:val>M?M:val);
32227 for (
int y=-d2; y<h; y+=d)
32228 for (
int x0=0; x0<w; x0+=d) {
32229 const int y0 =
cimg::mod(y,h), x1 = (x0 + d)%w, y1 = (y + d)%h, xc = (x0 + d2)%w, yc = (y + d2)%h;
32230 const Tfloat val = (Tfloat)(0.25f*(ref(xc,y0) + ref(x0,yc) + ref(xc,y1) + ref(x1,yc)) + r*
cimg::crand());
32231 ref(xc,yc) = (T)(val<m?m:val>M?M:val);
32233 for (
int y0=0; y0<h; y0+=d)
32234 for (
int x=-d2; x<w; x+=d) {
32235 const int x0 =
cimg::mod(x,w), x1 = (x + d)%w, y1 = (y0 + d)%h, xc = (x + d2)%w, yc = (y0 + d2)%h;
32236 const Tfloat val = (Tfloat)(0.25f*(ref(xc,y0) + ref(x0,yc) + ref(xc,y1) + ref(x1,yc)) + r*
cimg::crand());
32237 ref(xc,yc) = (T)(val<m?m:val>M?M:val);
32239 for (
int y=-d2; y<h; y+=d)
32240 for (
int x=-d2; x<w; x+=d) {
32241 const int x0 =
cimg::mod(x,w), y0 =
cimg::mod(y,h), x1 = (x + d)%w, y1 = (y + d)%h, xc = (x + d2)%w, yc = (y + d2)%h;
32242 const Tfloat val = (Tfloat)(0.25f*(ref(xc,y0) + ref(x0,yc) + ref(xc,y1) + ref(x1,yc)) + r*
cimg::crand());
32243 ref(xc,yc) = (T)(val<m?m:val>M?M:val);
32269 template<
typename tc>
32271 const CImg<tc>& colormap,
const float opacity=1,
32272 const double z0r=-2,
const double z0i=-2,
const double z1r=2,
const double z1i=2,
32273 const unsigned int iteration_max=255,
32274 const bool is_normalized_iteration=
false,
32275 const bool is_julia_set=
false,
32276 const double param_r=0,
const double param_i=0) {
32279 if (colormap) palette.assign(colormap._data,colormap.size()/colormap._spectrum,1,1,colormap._spectrum,
true);
32280 if (palette && palette._spectrum!=_spectrum)
32282 "draw_mandelbrot(): Instance and specified colormap (%u,%u,%u,%u,%p) have incompatible dimensions.",
32284 colormap._width,colormap._height,colormap._depth,colormap._spectrum,colormap._data);
32286 const float nopacity =
cimg::abs(opacity), copacity = 1 -
cimg::max(opacity,0), ln2 = (float)std::log(2.0);
32287 unsigned int iteration = 0;
32288 cimg_for_inXY(*
this,x0,y0,x1,y1,p,q) {
32289 const double x = z0r + p*(z1r-z0r)/_width, y = z0i + q*(z1i-z0i)/_height;
32290 double zr, zi, cr, ci;
32291 if (is_julia_set) { zr = x; zi = y; cr = param_r; ci = param_i; }
32292 else { zr = param_r; zi = param_i; cr = x; ci = y; }
32293 for (iteration=1; zr*zr + zi*zi<=4 && iteration<=iteration_max; ++iteration) {
32294 const double temp = zr*zr - zi*zi + cr;
32298 if (iteration>iteration_max) {
32300 if (opacity>=1) cimg_forC(*
this,c) (*this)(p,q,0,c) = (T)palette(0,c);
32301 else cimg_forC(*
this,c) (*this)(p,q,0,c) = (T)(palette(0,c)*nopacity + (*this)(p,q,0,c)*copacity);
32303 if (opacity>=1) cimg_forC(*
this,c) (*this)(p,q,0,c) = (T)0;
32304 else cimg_forC(*
this,c) (*this)(p,q,0,c) = (T)((*this)(p,q,0,c)*copacity);
32306 }
else if (is_normalized_iteration) {
32309 niteration = (float)(iteration + 1 - std::log(std::log(normz))/ln2);
32311 if (opacity>=1) cimg_forC(*
this,c) (*this)(p,q,0,c) = (T)palette._linear_atX(niteration,c);
32312 else cimg_forC(*
this,c) (*this)(p,q,0,c) = (T)(palette._linear_atX(niteration,c)*nopacity + (*this)(p,q,0,c)*copacity);
32314 if (opacity>=1) cimg_forC(*
this,c) (*this)(p,q,0,c) = (T)niteration;
32315 else cimg_forC(*
this,c) (*this)(p,q,0,c) = (T)(niteration*nopacity + (*this)(p,q,0,c)*copacity);
32319 if (opacity>=1) cimg_forC(*
this,c) (*this)(p,q,0,c) = (T)palette._atX(iteration,c);
32320 else cimg_forC(*
this,c) (*this)(p,q,0,c) = (T)(palette(iteration,c)*nopacity + (*this)(p,q,0,c)*copacity);
32322 if (opacity>=1) cimg_forC(*
this,c) (*this)(p,q,0,c) = (T)iteration;
32323 else cimg_forC(*
this,c) (*this)(p,q,0,c) = (T)(iteration*nopacity + (*this)(p,q,0,c)*copacity);
32331 template<
typename tc>
32333 const double z0r=-2,
const double z0i=-2,
const double z1r=2,
const double z1i=2,
32334 const unsigned int iteration_max=255,
32335 const bool is_normalized_iteration=
false,
32336 const bool is_julia_set=
false,
32337 const double param_r=0,
const double param_i=0) {
32339 z0r,z0i,z1r,z1i,iteration_max,is_normalized_iteration,is_julia_set,param_r,param_i);
32349 template<
typename tc>
32351 const tc *
const color,
const float opacity=1) {
32355 "draw_gaussian(): Specified color is (null).",
32357 const float sigma2 = 2*sigma*sigma, nopacity =
cimg::abs(opacity), copacity = 1 -
cimg::max(opacity,0);
32358 const unsigned long whd = (
unsigned long)_width*_height*_depth;
32359 const tc *col = color;
32360 cimg_forX(*
this,x) {
32361 const float dx = (x - xc), val = (
float)std::exp(-dx*dx/sigma2);
32362 T *ptrd =
data(x,0,0,0);
32363 if (opacity>=1) cimg_forC(*
this,c) { *ptrd = (T)(val*(*col++)); ptrd+=whd; }
32364 else cimg_forC(*
this,c) { *ptrd = (T)(nopacity*val*(*col++) + *ptrd*copacity); ptrd+=whd; }
32378 template<
typename t,
typename tc>
32380 const tc *
const color,
const float opacity=1) {
32382 if (tensor._width!=2 || tensor._height!=2 || tensor._depth!=1 || tensor._spectrum!=1)
32384 "draw_gaussian(): Specified tensor (%u,%u,%u,%u,%p) is not a 2x2 matrix.",
32386 tensor._width,tensor._height,tensor._depth,tensor._spectrum,tensor._data);
32389 "draw_gaussian(): Specified color is (null).",
32391 typedef typename CImg<t>::Tfloat tfloat;
32392 const CImg<tfloat> invT = tensor.get_invert(), invT2 = (invT*invT)/(-2.0);
32393 const tfloat a = invT2(0,0), b = 2*invT2(1,0), c = invT2(1,1);
32395 const unsigned long whd = (
unsigned long)_width*_height*_depth;
32396 const tc *col = color;
32398 cimg_forY(*
this,y) {
32400 cimg_forX(*
this,x) {
32401 const float val = (float)std::exp(a*dx*dx + b*dx*dy + c*dy*dy);
32402 T *ptrd =
data(x,y,0,0);
32403 if (opacity>=1) cimg_forC(*
this,c) { *ptrd = (T)(val*(*col++)); ptrd+=whd; }
32404 else cimg_forC(*
this,c) { *ptrd = (T)(nopacity*val*(*col++) + *ptrd*copacity); ptrd+=whd; }
32414 template<
typename tc>
32416 const tc *
const color,
const float opacity=1) {
32418 a = r1*ru*ru + r2*rv*rv,
32420 c = r1*rv*rv + r2*ru*ru;
32426 template<
typename tc>
32428 const tc *
const color,
const float opacity=1) {
32433 template<
typename t,
typename tc>
32435 const tc *
const color,
const float opacity=1) {
32437 typedef typename CImg<t>::Tfloat tfloat;
32438 if (tensor._width!=3 || tensor._height!=3 || tensor._depth!=1 || tensor._spectrum!=1)
32440 "draw_gaussian(): Specified tensor (%u,%u,%u,%u,%p) is not a 3x3 matrix.",
32442 tensor._width,tensor._height,tensor._depth,tensor._spectrum,tensor._data);
32444 const CImg<tfloat> invT = tensor.get_invert(), invT2 = (invT*invT)/(-2.0);
32445 const tfloat a = invT2(0,0), b = 2*invT2(1,0), c = 2*invT2(2,0), d = invT2(1,1), e = 2*invT2(2,1), f = invT2(2,2);
32447 const unsigned long whd = (
unsigned long)_width*_height*_depth;
32448 const tc *col = color;
32449 cimg_forXYZ(*
this,x,y,z) {
32451 dx = (x - xc), dy = (y - yc), dz = (z - zc),
32452 val = (
float)std::exp(a*dx*dx + b*dx*dy + c*dx*dz + d*dy*dy + e*dy*dz + f*dz*dz);
32453 T *ptrd =
data(x,y,z,0);
32454 if (opacity>=1) cimg_forC(*
this,c) { *ptrd = (T)(val*(*col++)); ptrd+=whd; }
32455 else cimg_forC(*
this,c) { *ptrd = (T)(nopacity*val*(*col++) + *ptrd*copacity); ptrd+=whd; }
32462 template<
typename tc>
32464 const tc *
const color,
const float opacity=1) {
32486 template<
typename tp,
typename tf,
typename tc,
typename to>
32490 const unsigned int render_type=4,
32491 const bool is_double_sided=
false,
const float focale=500,
32492 const float lightx=0,
const float lighty=0,
const float lightz=-5e8,
32493 const float specular_lightness=0.2f,
const float specular_shininess=0.1f) {
32494 return draw_object3d(x0,y0,z0,vertices,primitives,colors,opacities,render_type,is_double_sided,focale,lightx,lighty,lightz,
32499 template<
typename tp,
typename tf,
typename tc,
typename to,
typename tz>
32503 const unsigned int render_type,
32504 const bool is_double_sided,
const float focale,
32505 const float lightx,
const float lighty,
const float lightz,
32506 const float specular_lightness,
const float specular_shininess,
32508 return _draw_object3d(0,zbuffer,x0,y0,z0,vertices,primitives,colors,opacities,
32509 render_type,is_double_sided,focale,lightx,lighty,lightz,specular_lightness,specular_shininess,1);
32512 #ifdef cimg_use_board
32513 template<
typename tp,
typename tf,
typename tc,
typename to>
32515 const float x0,
const float y0,
const float z0,
32518 const unsigned int render_type=4,
32519 const bool is_double_sided=
false,
const float focale=500,
32520 const float lightx=0,
const float lighty=0,
const float lightz=-5e8,
32521 const float specular_lightness=0.2f,
const float specular_shininess=0.1f) {
32522 return draw_object3d(board,x0,y0,z0,vertices,primitives,colors,opacities,render_type,is_double_sided,focale,lightx,lighty,lightz,
32526 template<
typename tp,
typename tf,
typename tc,
typename to,
typename tz>
32528 const float x0,
const float y0,
const float z0,
32529 const CImg<tp>& vertices,
const CImgList<tf>& primitives,
32530 const CImgList<tc>& colors,
const CImg<to>& opacities,
32531 const unsigned int render_type,
32532 const bool is_double_sided,
const float focale,
32533 const float lightx,
const float lighty,
const float lightz,
32534 const float specular_lightness,
const float specular_shininess,
32535 CImg<tz>& zbuffer) {
32536 return _draw_object3d((
void*)&board,zbuffer,x0,y0,z0,vertices,primitives,colors,opacities,
32537 render_type,is_double_sided,focale,lightx,lighty,lightz,specular_lightness,specular_shininess,1);
32542 template<
typename tp,
typename tf,
typename tc,
typename to>
32546 const unsigned int render_type=4,
32547 const bool is_double_sided=
false,
const float focale=500,
32548 const float lightx=0,
const float lighty=0,
const float lightz=-5e8,
32549 const float specular_lightness=0.2f,
const float specular_shininess=0.1f) {
32550 return draw_object3d(x0,y0,z0,vertices,primitives,colors,opacities,render_type,is_double_sided,focale,lightx,lighty,lightz,
32555 template<
typename tp,
typename tf,
typename tc,
typename to,
typename tz>
32559 const unsigned int render_type,
32560 const bool is_double_sided,
const float focale,
32561 const float lightx,
const float lighty,
const float lightz,
32562 const float specular_lightness,
const float specular_shininess,
32564 return _draw_object3d(0,zbuffer,x0,y0,z0,vertices,primitives,colors,opacities,
32565 render_type,is_double_sided,focale,lightx,lighty,lightz,specular_lightness,specular_shininess,1);
32568 #ifdef cimg_use_board
32569 template<
typename tp,
typename tf,
typename tc,
typename to>
32571 const float x0,
const float y0,
const float z0,
32574 const unsigned int render_type=4,
32575 const bool is_double_sided=
false,
const float focale=500,
32576 const float lightx=0,
const float lighty=0,
const float lightz=-5e8,
32577 const float specular_lightness=0.2f,
const float specular_shininess=0.1f) {
32578 return draw_object3d(board,x0,y0,z0,vertices,primitives,colors,opacities,render_type,is_double_sided,focale,lightx,lighty,lightz,
32582 template<
typename tp,
typename tf,
typename tc,
typename to,
typename tz>
32584 const float x0,
const float y0,
const float z0,
32585 const CImg<tp>& vertices,
const CImgList<tf>& primitives,
32586 const CImgList<tc>& colors,
const CImgList<to>& opacities,
32587 const unsigned int render_type,
32588 const bool is_double_sided,
const float focale,
32589 const float lightx,
const float lighty,
const float lightz,
32590 const float specular_lightness,
const float specular_shininess,
32591 CImg<tz>& zbuffer) {
32592 return _draw_object3d((
void*)&board,zbuffer,x0,y0,z0,vertices,primitives,colors,opacities,
32593 render_type,is_double_sided,focale,lightx,lighty,lightz,specular_lightness,specular_shininess,1);
32598 template<
typename tp,
typename tf,
typename tc>
32602 const unsigned int render_type=4,
32603 const bool is_double_sided=
false,
const float focale=500,
32604 const float lightx=0,
const float lighty=0,
const float lightz=-5e8,
32605 const float specular_lightness=0.2f,
const float specular_shininess=0.1f) {
32607 render_type,is_double_sided,focale,lightx,lighty,lightz,specular_lightness,specular_shininess,
CImg<floatT>::empty());
32611 template<
typename tp,
typename tf,
typename tc,
typename tz>
32615 const unsigned int render_type,
32616 const bool is_double_sided,
const float focale,
32617 const float lightx,
const float lighty,
const float lightz,
32618 const float specular_lightness,
const float specular_shininess,
32621 render_type,is_double_sided,focale,lightx,lighty,lightz,specular_lightness,specular_shininess,zbuffer);
32624 #ifdef cimg_use_board
32625 template<
typename tp,
typename tf,
typename tc,
typename to>
32627 const float x0,
const float y0,
const float z0,
32630 const unsigned int render_type=4,
32631 const bool is_double_sided=
false,
const float focale=500,
32632 const float lightx=0,
const float lighty=0,
const float lightz=-5e8,
32633 const float specular_lightness=0.2f,
const float specular_shininess=0.1f) {
32635 render_type,is_double_sided,focale,lightx,lighty,lightz,specular_lightness,specular_shininess,
CImg<floatT>::empty());
32638 template<
typename tp,
typename tf,
typename tc,
typename to,
typename tz>
32640 const float x0,
const float y0,
const float z0,
32641 const CImg<tp>& vertices,
const CImgList<tf>& primitives,
32642 const CImgList<tc>& colors,
32643 const unsigned int render_type,
32644 const bool is_double_sided,
const float focale,
32645 const float lightx,
const float lighty,
const float lightz,
32646 const float specular_lightness,
const float specular_shininess,
32647 CImg<tz>& zbuffer) {
32649 render_type,is_double_sided,focale,lightx,lighty,lightz,specular_lightness,specular_shininess,zbuffer);
32653 template<
typename t>
32654 unsigned int ___draw_object3d(
const CImgList<t>& opacities,
const unsigned int n_primitive)
const {
32655 return (n_primitive>=opacities._width || opacities[n_primitive].is_empty())?1:opacities[n_primitive].
size();
32658 template<
typename t>
32659 unsigned int ___draw_object3d(
const CImg<t>&,
const unsigned int)
const {
32663 template<
typename tc,
typename to>
32664 void __draw_object3d(
const unsigned int n_primitive,
const CImgList<to>& opacities,
const CImg<tc>& color,
32665 const int nx0,
const int ny0,
const CImg<T>& sprite,
const float opac,
const float factor) {
32666 if (n_primitive<opacities._width && opacities[n_primitive]) {
32667 const CImg<to>& opacity = opacities[n_primitive];
32668 if (opacity.size()==1)
draw_image(nx0,ny0,sprite,opac);
32669 else if (opacity.is_sameXY(sprite))
draw_image(nx0,ny0,sprite,opacity);
32670 else if (opacity.is_sameXY(color))
draw_image(nx0,ny0,sprite,opacity.get_resize(sprite._width,sprite._height));
32673 W =
cimg::max(sprite._width,(
unsigned int)(opacity._width*factor)),
32674 H =
cimg::max(sprite._height,(
unsigned int)(opacity._height*factor));
32675 const CImg<T> __sprite = (sprite._width==W && sprite._height==H)?CImg<T>():sprite.get_resize(W,H), &_sprite = __sprite?__sprite:sprite;
32676 const CImg<to> __opacity = (opacity._width==W && opacity._height==H)?CImg<to>():opacity.get_resize(W,H), &_opacity = __opacity?__opacity:opacity;
32682 template<
typename tc,
typename to>
32683 void __draw_object3d(
const unsigned int,
const CImg<to>&,
const CImg<tc>&,
32684 const int nx0,
const int ny0,
const CImg<T>& sprite,
const float opac,
const float) {
32688 template<
typename tz,
typename tp,
typename tf,
typename tc,
typename to>
32689 CImg<T>& _draw_object3d(
void *
const pboard, CImg<tz>& zbuffer,
32690 const float X,
const float Y,
const float Z,
32691 const CImg<tp>& vertices,
32692 const CImgList<tf>& primitives,
32693 const CImgList<tc>& colors,
32694 const to& opacities,
32695 const unsigned int render_type,
32696 const bool is_double_sided,
const float focale,
32697 const float lightx,
const float lighty,
const float lightz,
32698 const float specular_lightness,
const float specular_shininess,
32699 const float sprite_scale) {
32700 typedef typename cimg::superset2<tp,tz,float>::type tpfloat;
32701 if (
is_empty() || !vertices || !primitives)
return *
this;
32702 char error_message[1024] = { 0 };
32703 if (!vertices.is_object3d(primitives,colors,opacities,
false,error_message))
32704 throw CImgArgumentException(_cimg_instance
32705 "draw_object3d(): Invalid specified 3d object (%u,%u) (%s).",
32706 cimg_instance,vertices._width,primitives._width,error_message);
32707 #ifndef cimg_use_board
32708 if (pboard)
return *
this;
32711 nspec = 1 - (specular_lightness<0.0f?0.0f:(specular_lightness>1.0f?1.0f:specular_lightness)),
32712 nspec2 = 1 + (specular_shininess<0.0f?0.0f:specular_shininess),
32713 nsl1 = (nspec2 - 1)/
cimg::sqr(nspec - 1),
32714 nsl2 = 1 - 2*nsl1*nspec,
32715 nsl3 = nspec2 - nsl1 - nsl2;
32718 CImg<floatT> light_texture;
32719 if (render_type==5) {
32720 if (colors._width>primitives._width) {
32721 static CImg<floatT> default_light_texture;
32722 static const tc *lptr = 0;
32723 static tc ref_values[64] = { 0 };
32724 const CImg<tc>& img = colors.back();
32725 bool is_same_texture = (lptr==img._data);
32726 if (is_same_texture)
32727 for (
unsigned int r = 0, j = 0; j<8; ++j)
32728 for (
unsigned int i = 0; i<8; ++i)
32729 if (ref_values[r++]!=img(i*img._width/9,j*img._height/9,0,(i+j)%img._spectrum)) { is_same_texture =
false;
break; }
32730 if (!is_same_texture || default_light_texture._spectrum<_spectrum) {
32731 (default_light_texture.assign(img,
false)/=255).
resize(-100,-100,1,_spectrum);
32732 lptr = colors.back().data();
32733 for (
unsigned int r = 0, j = 0; j<8; ++j)
32734 for (
unsigned int i = 0; i<8; ++i)
32735 ref_values[r++] = img(i*img._width/9,j*img._height/9,0,(i+j)%img._spectrum);
32737 light_texture.assign(default_light_texture,
true);
32739 static CImg<floatT> default_light_texture;
32740 static float olightx = 0, olighty = 0, olightz = 0, ospecular_shininess = 0;
32741 if (!default_light_texture ||
32742 lightx!=olightx || lighty!=olighty || lightz!=olightz ||
32743 specular_shininess!=ospecular_shininess || default_light_texture._spectrum<_spectrum) {
32744 default_light_texture.assign(512,512);
32749 nl = (float)std::sqrt(dlx*dlx + dly*dly + dlz*dlz),
32750 nlx = default_light_texture._width/2*(1 + dlx/nl),
32751 nly = default_light_texture._height/2*(1 + dly/nl),
32753 default_light_texture.draw_gaussian(nlx,nly,default_light_texture._width/3.0f,white);
32754 cimg_forXY(default_light_texture,x,y) {
32755 const float factor = default_light_texture(x,y);
32756 if (factor>nspec) default_light_texture(x,y) =
cimg::min(2,nsl1*factor*factor + nsl2*factor + nsl3);
32758 default_light_texture.resize(-100,-100,1,_spectrum);
32759 olightx = lightx; olighty = lighty; olightz = lightz; ospecular_shininess = specular_shininess;
32761 light_texture.assign(default_light_texture,
true);
32766 CImg<tpfloat> projections(vertices._width,2);
32767 tpfloat parallzmin = cimg::type<tpfloat>::max();
32769 absfocale = focale?
cimg::abs(focale):0,
32770 _focale = absfocale?absfocale:(1-parallzmin);
32771 if (absfocale) cimg_forX(projections,l) {
32773 x = (tpfloat)vertices(l,0),
32774 y = (tpfloat)vertices(l,1),
32775 z = (tpfloat)vertices(l,2);
32776 const tpfloat projectedz = z + Z + absfocale;
32777 projections(l,1) = Y + absfocale*y/projectedz;
32778 projections(l,0) = X + absfocale*x/projectedz;
32779 }
else cimg_forX(projections,l) {
32781 x = (tpfloat)vertices(l,0),
32782 y = (tpfloat)vertices(l,1),
32783 z = (tpfloat)vertices(l,2);
32784 if (z<parallzmin) parallzmin = z;
32785 projections(l,1) = Y + y;
32786 projections(l,0) = X + x;
32790 CImg<uintT> visibles(primitives._width);
32791 CImg<tpfloat> zrange(primitives._width);
32792 unsigned int nb_visibles = 0;
32793 const tpfloat zmin = absfocale?(tpfloat)(1.5f - absfocale):cimg::type<tpfloat>::
min();
32794 cimglist_for(primitives,l) {
32795 const CImg<tf>& primitive = primitives[l];
32796 switch (primitive.size()) {
32798 const unsigned int i0 = (
unsigned int)primitive(0);
32799 const tpfloat z0 = Z + vertices(i0,2);
32801 visibles(nb_visibles) = (
unsigned int)l;
32802 zrange(nb_visibles++) = z0;
32807 i0 = (
unsigned int)primitive(0),
32808 i1 = (
unsigned int)primitive(1);
32810 Xc = 0.5f*((float)vertices(i0,0) + (float)vertices(i1,0)),
32811 Yc = 0.5f*((
float)vertices(i0,1) + (float)vertices(i1,1)),
32812 Zc = 0.5f*((
float)vertices(i0,2) + (float)vertices(i1,2)),
32814 zc = _zc + _focale,
32815 xc = X + Xc*(absfocale?absfocale/zc:1),
32816 yc = Y + Yc*(absfocale?absfocale/zc:1),
32817 radius = 0.5f*std::sqrt(
cimg::sqr(vertices(i1,0) - vertices(i0,0)) +
32818 cimg::sqr(vertices(i1,1) - vertices(i0,1)) +
32819 cimg::sqr(vertices(i1,2) - vertices(i0,2)))*(absfocale?absfocale/zc:1),
32824 if (xM>=0 && xm<_width && yM>=0 && ym<_height && _zc>zmin) {
32825 visibles(nb_visibles) = (
unsigned int)l;
32826 zrange(nb_visibles++) = _zc;
32832 i0 = (
unsigned int)primitive(0),
32833 i1 = (
unsigned int)primitive(1);
32835 x0 = projections(i0,0), y0 = projections(i0,1), z0 = Z + vertices(i0,2),
32836 x1 = projections(i1,0), y1 = projections(i1,1), z1 = Z + vertices(i1,2);
32837 tpfloat xm, xM, ym, yM;
32838 if (x0<x1) { xm = x0; xM = x1; }
else { xm = x1; xM = x0; }
32839 if (y0<y1) { ym = y0; yM = y1; }
else { ym = y1; yM = y0; }
32840 if (xM>=0 && xm<_width && yM>=0 && ym<_height && z0>zmin && z1>zmin) {
32841 visibles(nb_visibles) = (
unsigned int)l;
32842 zrange(nb_visibles++) = (z0 + z1)/2;
32848 i0 = (
unsigned int)primitive(0),
32849 i1 = (
unsigned int)primitive(1),
32850 i2 = (
unsigned int)primitive(2);
32852 x0 = projections(i0,0), y0 = projections(i0,1), z0 = Z + vertices(i0,2),
32853 x1 = projections(i1,0), y1 = projections(i1,1), z1 = Z + vertices(i1,2),
32854 x2 = projections(i2,0), y2 = projections(i2,1), z2 = Z + vertices(i2,2);
32855 tpfloat xm, xM, ym, yM;
32856 if (x0<x1) { xm = x0; xM = x1; }
else { xm = x1; xM = x0; }
32857 if (x2<xm) xm = x2;
32858 if (x2>xM) xM = x2;
32859 if (y0<y1) { ym = y0; yM = y1; }
else { ym = y1; yM = y0; }
32860 if (y2<ym) ym = y2;
32861 if (y2>yM) yM = y2;
32862 if (xM>=0 && xm<_width && yM>=0 && ym<_height && z0>zmin && z1>zmin && z2>zmin) {
32863 const tpfloat d = (x1-x0)*(y2-y0) - (x2-x0)*(y1-y0);
32864 if (is_double_sided || d<0) {
32865 visibles(nb_visibles) = (
unsigned int)l;
32866 zrange(nb_visibles++) = (z0 + z1 + z2)/3;
32873 i0 = (
unsigned int)primitive(0),
32874 i1 = (
unsigned int)primitive(1),
32875 i2 = (
unsigned int)primitive(2),
32876 i3 = (
unsigned int)primitive(3);
32878 x0 = projections(i0,0), y0 = projections(i0,1), z0 = Z + vertices(i0,2),
32879 x1 = projections(i1,0), y1 = projections(i1,1), z1 = Z + vertices(i1,2),
32880 x2 = projections(i2,0), y2 = projections(i2,1), z2 = Z + vertices(i2,2),
32881 x3 = projections(i3,0), y3 = projections(i3,1), z3 = Z + vertices(i3,2);
32882 tpfloat xm, xM, ym, yM;
32883 if (x0<x1) { xm = x0; xM = x1; }
else { xm = x1; xM = x0; }
32884 if (x2<xm) xm = x2;
32885 if (x2>xM) xM = x2;
32886 if (x3<xm) xm = x3;
32887 if (x3>xM) xM = x3;
32888 if (y0<y1) { ym = y0; yM = y1; }
else { ym = y1; yM = y0; }
32889 if (y2<ym) ym = y2;
32890 if (y2>yM) yM = y2;
32891 if (y3<ym) ym = y3;
32892 if (y3>yM) yM = y3;
32893 if (xM>=0 && xm<_width && yM>=0 && ym<_height && z0>zmin && z1>zmin && z2>zmin) {
32894 const float d = (x1 - x0)*(y2 - y0) - (x2 - x0)*(y1 - y0);
32895 if (is_double_sided || d<0) {
32896 visibles(nb_visibles) = (
unsigned int)l;
32897 zrange(nb_visibles++) = (z0 + z1 + z2 + z3)/4;
32902 throw CImgArgumentException(_cimg_instance
32903 "draw_object3d(): Invalid primitive[%u] with size %u "
32904 "(should have size 1,2,3,4,5,6,9 or 12).",
32906 l,primitive.size());
32909 if (nb_visibles<=0)
return *
this;
32910 CImg<uintT> permutations;
32911 CImg<tpfloat>(zrange._data,nb_visibles,1,1,1,
true).
sort(permutations,
false);
32914 CImg<floatT> lightprops;
32915 switch (render_type) {
32917 lightprops.assign(nb_visibles);
32918 cimg_forX(lightprops,l) {
32919 const CImg<tf>& primitive = primitives(visibles(permutations(l)));
32920 const unsigned int psize = primitive.size();
32921 if (psize==3 || psize==4 || psize==9 || psize==12) {
32923 i0 = (
unsigned int)primitive(0),
32924 i1 = (
unsigned int)primitive(1),
32925 i2 = (
unsigned int)primitive(2);
32927 x0 = (tpfloat)vertices(i0,0), y0 = (tpfloat)vertices(i0,1), z0 = (tpfloat)vertices(i0,2),
32928 x1 = (tpfloat)vertices(i1,0), y1 = (tpfloat)vertices(i1,1), z1 = (tpfloat)vertices(i1,2),
32929 x2 = (tpfloat)vertices(i2,0), y2 = (tpfloat)vertices(i2,1), z2 = (tpfloat)vertices(i2,2),
32930 dx1 = x1 - x0, dy1 = y1 - y0, dz1 = z1 - z0,
32931 dx2 = x2 - x0, dy2 = y2 - y0, dz2 = z2 - z0,
32932 nx = dy1*dz2 - dz1*dy2,
32933 ny = dz1*dx2 - dx1*dz2,
32934 nz = dx1*dy2 - dy1*dx2,
32935 norm = (tpfloat)std::sqrt(1e-5f + nx*nx + ny*ny + nz*nz),
32936 lx = X + (x0 + x1 + x2)/3 - lightx,
32937 ly = Y + (y0 + y1 + y2)/3 - lighty,
32938 lz = Z + (z0 + z1 + z2)/3 - lightz,
32939 nl = (tpfloat)std::
sqrt(1e-5f + lx*lx + ly*ly + lz*lz),
32940 factor = cimg::
max(cimg::
abs(-lx*nx-ly*ny-lz*nz)/(norm*nl),0);
32941 lightprops[l] = factor<=nspec?factor:(nsl1*factor*factor + nsl2*factor + nsl3);
32942 } else lightprops[l] = 1;
32948 CImg<tpfloat> vertices_normals(vertices._width,3,1,1,0);
32949 for (
unsigned int l = 0; l<nb_visibles; ++l) {
32950 const CImg<tf>& primitive = primitives[visibles(l)];
32951 const unsigned int psize = primitive.size();
32953 triangle_flag = (psize==3) || (psize==9),
32954 rectangle_flag = (psize==4) || (psize==12);
32955 if (triangle_flag || rectangle_flag) {
32957 i0 = (
unsigned int)primitive(0),
32958 i1 = (
unsigned int)primitive(1),
32959 i2 = (
unsigned int)primitive(2),
32960 i3 = rectangle_flag?(
unsigned int)primitive(3):0;
32962 x0 = (tpfloat)vertices(i0,0), y0 = (tpfloat)vertices(i0,1), z0 = (tpfloat)vertices(i0,2),
32963 x1 = (tpfloat)vertices(i1,0), y1 = (tpfloat)vertices(i1,1), z1 = (tpfloat)vertices(i1,2),
32964 x2 = (tpfloat)vertices(i2,0), y2 = (tpfloat)vertices(i2,1), z2 = (tpfloat)vertices(i2,2),
32965 dx1 = x1 - x0, dy1 = y1 - y0, dz1 = z1 - z0,
32966 dx2 = x2 - x0, dy2 = y2 - y0, dz2 = z2 - z0,
32967 nnx = dy1*dz2 - dz1*dy2,
32968 nny = dz1*dx2 - dx1*dz2,
32969 nnz = dx1*dy2 - dy1*dx2,
32970 norm = (tpfloat)(1e-5f + std::sqrt(nnx*nnx + nny*nny + nnz*nnz)),
32974 vertices_normals(i0,0)+=nx; vertices_normals(i0,1)+=ny; vertices_normals(i0,2)+=nz;
32975 vertices_normals(i1,0)+=nx; vertices_normals(i1,1)+=ny; vertices_normals(i1,2)+=nz;
32976 vertices_normals(i2,0)+=nx; vertices_normals(i2,1)+=ny; vertices_normals(i2,2)+=nz;
32977 if (rectangle_flag) { vertices_normals(i3,0)+=nx; vertices_normals(i3,1)+=ny; vertices_normals(i3,2)+=nz; }
32981 if (is_double_sided) cimg_forX(vertices_normals,p) if (vertices_normals(p,2)>0) {
32982 vertices_normals(p,0) = -vertices_normals(p,0);
32983 vertices_normals(p,1) = -vertices_normals(p,1);
32984 vertices_normals(p,2) = -vertices_normals(p,2);
32987 if (render_type==4) {
32988 lightprops.assign(vertices._width);
32989 cimg_forX(lightprops,l) {
32991 nx = vertices_normals(l,0),
32992 ny = vertices_normals(l,1),
32993 nz = vertices_normals(l,2),
32994 norm = (tpfloat)std::sqrt(1e-5f + nx*nx + ny*ny + nz*nz),
32995 lx = X + vertices(l,0) - lightx,
32996 ly = Y + vertices(l,1) - lighty,
32997 lz = Z + vertices(l,2) - lightz,
32998 nl = (tpfloat)std::sqrt(1e-5f + lx*lx + ly*ly + lz*lz),
32999 factor =
cimg::max((-lx*nx-ly*ny-lz*nz)/(norm*nl),0);
33000 lightprops[l] = factor<=nspec?factor:(nsl1*factor*factor + nsl2*factor + nsl3);
33004 lw2 = light_texture._width/2 - 1,
33005 lh2 = light_texture._height/2 - 1;
33006 lightprops.assign(vertices._width,2);
33007 cimg_forX(lightprops,l) {
33009 nx = vertices_normals(l,0),
33010 ny = vertices_normals(l,1),
33011 nz = vertices_normals(l,2),
33012 norm = (tpfloat)std::sqrt(1e-5f + nx*nx + ny*ny + nz*nz),
33015 lightprops(l,0) = lw2*(1 + nnx);
33016 lightprops(l,1) = lh2*(1 + nny);
33023 const CImg<tc> default_color(1,_spectrum,1,1,(tc)200);
33024 for (
unsigned int l = 0; l<nb_visibles; ++l) {
33025 const unsigned int n_primitive = visibles(permutations(l));
33026 const CImg<tf>& primitive = primitives[n_primitive];
33028 &__color = n_primitive<colors._width?colors[n_primitive]:CImg<tc>(),
33029 _color = (__color && __color.size()!=_spectrum && __color._spectrum<_spectrum)?colors[n_primitive].
get_resize(-100,-100,-100,_spectrum,0):
CImg<tc>(),
33030 &color = _color?_color:(__color?__color:default_color);
33031 const tc *
const pcolor = color._data;
33032 const unsigned int siz_opac = ___draw_object3d(opacities,n_primitive);
33033 const float opac = (n_primitive>=opacities._width || !siz_opac)?1.0f:opacities(n_primitive,0);
33035 #ifdef cimg_use_board
33036 LibBoard::Board &board = *(LibBoard::Board*)pboard;
33039 switch (primitive.size()) {
33041 const unsigned int n0 = (
unsigned int)primitive[0];
33042 const int x0 = (int)projections(n0,0), y0 = (int)projections(n0,1);
33043 if (color.size()==_spectrum && siz_opac==1) {
33045 #ifdef cimg_use_board
33047 board.setPenColorRGBi(color[0],color[1],color[2],(
unsigned char)(opac*255));
33048 board.fillCircle((
float)x0,
height()-(
float)y0,0);
33053 throw CImgArgumentException(_cimg_instance
33054 "draw_object3d(): Undefined texture for sprite primitive [%u].",
33055 cimg_instance,n_primitive);
33056 const tpfloat z = Z + vertices(n0,2);
33057 const float factor = focale<0?1:sprite_scale*(absfocale?absfocale/(z + absfocale):1);
33059 _sw = (
unsigned int)(color._width*factor),
33060 _sh = (
unsigned int)(color._height*factor),
33061 sw = _sw?_sw:1, sh = _sh?_sh:1;
33062 const int nx0 = x0 - (int)sw/2, ny0 = y0 - (
int)sh/2;
33063 if (sw<=3*_width/2 && sh<=3*_height/2 && (nx0+(
int)sw/2>=0 || nx0-(
int)sw/2<width() || ny0+(
int)sh/2>=0 || ny0-(
int)sh/2<
height())) {
33065 _sprite = (sw!=color._width || sh!=color._height)?color.get_resize(sw,sh,1,-100,render_type<=3?1:3):CImg<tc>(),
33066 &sprite = _sprite?_sprite:color;
33067 __draw_object3d(n_primitive,opacities,color,nx0,ny0,sprite,opac,factor);
33068 #ifdef cimg_use_board
33070 board.setPenColorRGBi(128,128,128);
33071 board.setFillColor(LibBoard::Color::None);
33072 board.drawRectangle((
float)nx0,
height()-(
float)ny0,sw,sh);
33080 n0 = (
unsigned int)primitive[0],
33081 n1 = (
unsigned int)primitive[1];
33083 x0 = (int)projections(n0,0), y0 = (int)projections(n0,1),
33084 x1 = (int)projections(n1,0), y1 = (int)projections(n1,1);
33086 z0 = vertices(n0,2) + Z + _focale,
33087 z1 = vertices(n1,2) + Z + _focale;
33089 if (zbuffer)
draw_line(zbuffer,x0,y0,z0,x1,y1,z1,pcolor,opac);
33090 else draw_line(x0,y0,x1,y1,pcolor,opac);
33091 #ifdef cimg_use_board
33093 board.setPenColorRGBi(color[0],color[1],color[2],(
unsigned char)(opac*255));
33094 board.drawLine((
float)x0,
height()-(
float)y0,x1,
height()-(
float)y1);
33098 draw_point(x0,y0,pcolor,opac).draw_point(x1,y1,pcolor,opac);
33099 #ifdef cimg_use_board
33101 board.setPenColorRGBi(color[0],color[1],color[2],(
unsigned char)(opac*255));
33102 board.drawCircle((
float)x0,
height()-(
float)y0,0);
33103 board.drawCircle((
float)x1,
height()-(
float)y1,0);
33110 n0 = (
unsigned int)primitive[0],
33111 n1 = (
unsigned int)primitive[1];
33113 Xc = 0.5f*((float)vertices(n0,0) + (float)vertices(n1,0)),
33114 Yc = 0.5f*((
float)vertices(n0,1) + (float)vertices(n1,1)),
33115 Zc = 0.5f*((
float)vertices(n0,2) + (float)vertices(n1,2)),
33116 zc = Z + Zc + _focale,
33117 xc = X + Xc*(absfocale?absfocale/zc:1),
33118 yc = Y + Yc*(absfocale?absfocale/zc:1),
33119 radius = 0.5f*std::sqrt(
cimg::sqr(vertices(n1,0) - vertices(n0,0)) +
33120 cimg::sqr(vertices(n1,1) - vertices(n0,1)) +
33121 cimg::sqr(vertices(n1,2) - vertices(n0,2)))*(absfocale?absfocale/zc:1);
33122 switch (render_type) {
33125 #ifdef cimg_use_board
33127 board.setPenColorRGBi(color[0],color[1],color[2],(
unsigned char)(opac*255));
33128 board.fillCircle(xc,
height()-yc,0);
33133 draw_circle((
int)xc,(
int)yc,(
int)radius,pcolor,opac,~0U);
33134 #ifdef cimg_use_board
33136 board.setPenColorRGBi(color[0],color[1],color[2],(
unsigned char)(opac*255));
33137 board.setFillColor(LibBoard::Color::None);
33138 board.drawCircle(xc,
height()-yc,radius);
33143 draw_circle((
int)xc,(
int)yc,(
int)radius,pcolor,opac);
33144 #ifdef cimg_use_board
33146 board.setPenColorRGBi(color[0],color[1],color[2],(
unsigned char)(opac*255));
33147 board.fillCircle(xc,
height()-yc,radius);
33155 throw CImgArgumentException(_cimg_instance
33156 "draw_object3d(): Undefined texture for line primitive [%u].",
33157 cimg_instance,n_primitive);
33159 n0 = (
unsigned int)primitive[0],
33160 n1 = (
unsigned int)primitive[1],
33161 tx0 = (
unsigned int)primitive[2],
33162 ty0 = (
unsigned int)primitive[3],
33163 tx1 = (
unsigned int)primitive[4],
33164 ty1 = (
unsigned int)primitive[5];
33166 x0 = (int)projections(n0,0), y0 = (int)projections(n0,1),
33167 x1 = (int)projections(n1,0), y1 = (int)projections(n1,1);
33169 z0 = vertices(n0,2) + Z + _focale,
33170 z1 = vertices(n1,2) + Z + _focale;
33172 if (zbuffer)
draw_line(zbuffer,x0,y0,z0,x1,y1,z1,color,tx0,ty0,tx1,ty1,opac);
33173 else draw_line(x0,y0,x1,y1,color,tx0,ty0,tx1,ty1,opac);
33174 #ifdef cimg_use_board
33176 board.setPenColorRGBi(128,128,128,(
unsigned char)(opac*255));
33177 board.drawLine((
float)x0,
height()-(
float)y0,(
float)x1,
height()-(
float)y1);
33181 draw_point(x0,y0,color.get_vector_at(tx0,ty0)._data,opac).
33182 draw_point(x1,y1,color.get_vector_at(tx1,ty1)._data,opac);
33183 #ifdef cimg_use_board
33185 board.setPenColorRGBi(128,128,128,(
unsigned char)(opac*255));
33186 board.drawCircle((
float)x0,
height()-(
float)y0,0);
33187 board.drawCircle((
float)x1,
height()-(
float)y1,0);
33194 n0 = (
unsigned int)primitive[0],
33195 n1 = (
unsigned int)primitive[1],
33196 n2 = (
unsigned int)primitive[2];
33198 x0 = (int)projections(n0,0), y0 = (int)projections(n0,1),
33199 x1 = (int)projections(n1,0), y1 = (int)projections(n1,1),
33200 x2 = (int)projections(n2,0), y2 = (int)projections(n2,1);
33202 z0 = vertices(n0,2) + Z + _focale,
33203 z1 = vertices(n1,2) + Z + _focale,
33204 z2 = vertices(n2,2) + Z + _focale;
33205 switch (render_type) {
33207 draw_point(x0,y0,pcolor,opac).draw_point(x1,y1,pcolor,opac).draw_point(x2,y2,pcolor,opac);
33208 #ifdef cimg_use_board
33210 board.setPenColorRGBi(color[0],color[1],color[2],(
unsigned char)(opac*255));
33211 board.drawCircle((
float)x0,
height()-(
float)y0,0);
33212 board.drawCircle((
float)x1,
height()-(
float)y1,0);
33213 board.drawCircle((
float)x2,
height()-(
float)y2,0);
33219 draw_line(zbuffer,x0,y0,z0,x1,y1,z1,pcolor,opac).draw_line(zbuffer,x0,y0,z0,x2,y2,z2,pcolor,opac).
33220 draw_line(zbuffer,x1,y1,z1,x2,y2,z2,pcolor,opac);
33222 draw_line(x0,y0,x1,y1,pcolor,opac).draw_line(x0,y0,x2,y2,pcolor,opac).
33224 #ifdef cimg_use_board
33226 board.setPenColorRGBi(color[0],color[1],color[2],(
unsigned char)(opac*255));
33227 board.drawLine((
float)x0,
height()-(
float)y0,(
float)x1,
height()-(
float)y1);
33228 board.drawLine((
float)x0,
height()-(
float)y0,(
float)x2,
height()-(
float)y2);
33229 board.drawLine((
float)x1,
height()-(
float)y1,(
float)x2,
height()-(
float)y2);
33234 if (zbuffer)
draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,pcolor,opac);
33236 #ifdef cimg_use_board
33238 board.setPenColorRGBi(color[0],color[1],color[2],(
unsigned char)(opac*255));
33239 board.fillTriangle((
float)x0,
height()-(
float)y0,(
float)x1,
height()-(
float)y1,(
float)x2,
height()-(
float)y2);
33244 if (zbuffer)
draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,pcolor,opac,lightprops(l));
33245 else _draw_triangle(x0,y0,x1,y1,x2,y2,pcolor,opac,lightprops(l));
33246 #ifdef cimg_use_board
33248 const float lp =
cimg::min(lightprops(l),1);
33249 board.setPenColorRGBi((
unsigned char)(color[0]*lp),
33250 (
unsigned char)(color[1]*lp),
33251 (
unsigned char)(color[2]*lp),
33252 (
unsigned char)(opac*255));
33253 board.fillTriangle((
float)x0,
height()-(
float)y0,(
float)x1,
height()-(
float)y1,(
float)x2,
height()-(
float)y2);
33258 if (zbuffer)
draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,pcolor,lightprops(n0),lightprops(n1),lightprops(n2),opac);
33259 else draw_triangle(x0,y0,x1,y1,x2,y2,pcolor,lightprops(n0),lightprops(n1),lightprops(n2),opac);
33260 #ifdef cimg_use_board
33262 board.setPenColorRGBi((
unsigned char)(color[0]),
33263 (
unsigned char)(color[1]),
33264 (
unsigned char)(color[2]),
33265 (
unsigned char)(opac*255));
33266 board.fillGouraudTriangle((
float)x0,
height()-(
float)y0,lightprops(n0),
33267 (
float)x1,
height()-(
float)y1,lightprops(n1),
33268 (
float)x2,
height()-(
float)y2,lightprops(n2));
33274 lx0 = (
unsigned int)lightprops(n0,0), ly0 = (
unsigned int)lightprops(n0,1),
33275 lx1 = (
unsigned int)lightprops(n1,0), ly1 = (
unsigned int)lightprops(n1,1),
33276 lx2 = (
unsigned int)lightprops(n2,0), ly2 = (
unsigned int)lightprops(n2,1);
33277 if (zbuffer)
draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,pcolor,light_texture,lx0,ly0,lx1,ly1,lx2,ly2,opac);
33278 else draw_triangle(x0,y0,x1,y1,x2,y2,pcolor,light_texture,lx0,ly0,lx1,ly1,lx2,ly2,opac);
33279 #ifdef cimg_use_board
33282 l0 = light_texture((
int)(light_texture.width()/2*(1+lightprops(n0,0))), (int)(light_texture.height()/2*(1+lightprops(n0,1)))),
33283 l1 = light_texture((
int)(light_texture.width()/2*(1+lightprops(n1,0))), (int)(light_texture.height()/2*(1+lightprops(n1,1)))),
33284 l2 = light_texture((
int)(light_texture.width()/2*(1+lightprops(n2,0))), (int)(light_texture.height()/2*(1+lightprops(n2,1))));
33285 board.setPenColorRGBi((
unsigned char)(color[0]),
33286 (
unsigned char)(color[1]),
33287 (
unsigned char)(color[2]),
33288 (
unsigned char)(opac*255));
33289 board.fillGouraudTriangle((
float)x0,
height()-(
float)y0,l0,
33290 (
float)x1,
height()-(
float)y1,l1,
33291 (
float)x2,
height()-(
float)y2,l2);
33299 n0 = (
unsigned int)primitive[0],
33300 n1 = (
unsigned int)primitive[1],
33301 n2 = (
unsigned int)primitive[2],
33302 n3 = (
unsigned int)primitive[3];
33304 x0 = (int)projections(n0,0), y0 = (int)projections(n0,1),
33305 x1 = (int)projections(n1,0), y1 = (int)projections(n1,1),
33306 x2 = (int)projections(n2,0), y2 = (int)projections(n2,1),
33307 x3 = (int)projections(n3,0), y3 = (int)projections(n3,1);
33309 z0 = vertices(n0,2) + Z + _focale,
33310 z1 = vertices(n1,2) + Z + _focale,
33311 z2 = vertices(n2,2) + Z + _focale,
33312 z3 = vertices(n3,2) + Z + _focale;
33313 switch (render_type) {
33315 draw_point(x0,y0,pcolor,opac).draw_point(x1,y1,pcolor,opac).
33316 draw_point(x2,y2,pcolor,opac).draw_point(x3,y3,pcolor,opac);
33317 #ifdef cimg_use_board
33319 board.setPenColorRGBi(color[0],color[1],color[2],(
unsigned char)(opac*255));
33320 board.drawCircle((
float)x0,
height()-(
float)y0,0);
33321 board.drawCircle((
float)x1,
height()-(
float)y1,0);
33322 board.drawCircle((
float)x2,
height()-(
float)y2,0);
33323 board.drawCircle((
float)x3,
height()-(
float)y3,0);
33329 draw_line(zbuffer,x0,y0,z0,x1,y1,z1,pcolor,opac).draw_line(zbuffer,x1,y1,z1,x2,y2,z2,pcolor,opac).
33330 draw_line(zbuffer,x2,y2,z2,x3,y3,z3,pcolor,opac).draw_line(zbuffer,x3,y3,z3,x0,y0,z0,pcolor,opac);
33332 draw_line(x0,y0,x1,y1,pcolor,opac).draw_line(x1,y1,x2,y2,pcolor,opac).
33333 draw_line(x2,y2,x3,y3,pcolor,opac).draw_line(x3,y3,x0,y0,pcolor,opac);
33334 #ifdef cimg_use_board
33336 board.setPenColorRGBi(color[0],color[1],color[2],(
unsigned char)(opac*255));
33337 board.drawLine((
float)x0,
height()-(
float)y0,(
float)x1,
height()-(
float)y1);
33338 board.drawLine((
float)x1,
height()-(
float)y1,(
float)x2,
height()-(
float)y2);
33339 board.drawLine((
float)x2,
height()-(
float)y2,(
float)x3,
height()-(
float)y3);
33340 board.drawLine((
float)x3,
height()-(
float)y3,(
float)x0,
height()-(
float)y0);
33346 draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,pcolor,opac).draw_triangle(zbuffer,x0,y0,z0,x2,y2,z2,x3,y3,z3,pcolor,opac);
33348 draw_triangle(x0,y0,x1,y1,x2,y2,pcolor,opac).draw_triangle(x0,y0,x2,y2,x3,y3,pcolor,opac);
33349 #ifdef cimg_use_board
33351 board.setPenColorRGBi(color[0],color[1],color[2],(
unsigned char)(opac*255));
33352 board.fillTriangle((
float)x0,
height()-(
float)y0,(
float)x1,
height()-(
float)y1,(
float)x2,
height()-(
float)y2);
33353 board.fillTriangle((
float)x0,
height()-(
float)y0,(
float)x2,
height()-(
float)y2,(
float)x3,
height()-(
float)y3);
33359 draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,pcolor,opac,lightprops(l)).
33360 draw_triangle(zbuffer,x0,y0,z0,x2,y2,z2,x3,y3,z3,pcolor,opac,lightprops(l));
33362 _draw_triangle(x0,y0,x1,y1,x2,y2,pcolor,opac,lightprops(l)).
33363 _draw_triangle(x0,y0,x2,y2,x3,y3,pcolor,opac,lightprops(l));
33364 #ifdef cimg_use_board
33366 const float lp =
cimg::min(lightprops(l),1);
33367 board.setPenColorRGBi((
unsigned char)(color[0]*lp),
33368 (
unsigned char)(color[1]*lp),
33369 (
unsigned char)(color[2]*lp),(
unsigned char)(opac*255));
33370 board.fillTriangle((
float)x0,
height()-(
float)y0,(
float)x1,
height()-(
float)y1,(
float)x2,
height()-(
float)y2);
33371 board.fillTriangle((
float)x0,
height()-(
float)y0,(
float)x2,
height()-(
float)y2,(
float)x3,
height()-(
float)y3);
33377 lightprop0 = lightprops(n0), lightprop1 = lightprops(n1),
33378 lightprop2 = lightprops(n2), lightprop3 = lightprops(n3);
33380 draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,pcolor,lightprop0,lightprop1,lightprop2,opac).
33381 draw_triangle(zbuffer,x0,y0,z0,x2,y2,z2,x3,y3,z3,pcolor,lightprop0,lightprop2,lightprop3,opac);
33383 draw_triangle(x0,y0,x1,y1,x2,y2,pcolor,lightprop0,lightprop1,lightprop2,opac).
33384 draw_triangle(x0,y0,x2,y2,x3,y3,pcolor,lightprop0,lightprop2,lightprop3,opac);
33385 #ifdef cimg_use_board
33387 board.setPenColorRGBi((
unsigned char)(color[0]),
33388 (
unsigned char)(color[1]),
33389 (
unsigned char)(color[2]),
33390 (
unsigned char)(opac*255));
33391 board.fillGouraudTriangle((
float)x0,
height()-(
float)y0,lightprop0,
33392 (
float)x1,
height()-(
float)y1,lightprop1,
33393 (
float)x2,
height()-(
float)y2,lightprop2);
33394 board.fillGouraudTriangle((
float)x0,
height()-(
float)y0,lightprop0,
33395 (
float)x2,
height()-(
float)y2,lightprop2,
33396 (
float)x3,
height()-(
float)y3,lightprop3);
33402 lx0 = (
unsigned int)lightprops(n0,0), ly0 = (
unsigned int)lightprops(n0,1),
33403 lx1 = (
unsigned int)lightprops(n1,0), ly1 = (
unsigned int)lightprops(n1,1),
33404 lx2 = (
unsigned int)lightprops(n2,0), ly2 = (
unsigned int)lightprops(n2,1),
33405 lx3 = (
unsigned int)lightprops(n3,0), ly3 = (
unsigned int)lightprops(n3,1);
33407 draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,pcolor,light_texture,lx0,ly0,lx1,ly1,lx2,ly2,opac).
33408 draw_triangle(zbuffer,x0,y0,z0,x2,y2,z2,x3,y3,z3,pcolor,light_texture,lx0,ly0,lx2,ly2,lx3,ly3,opac);
33410 draw_triangle(x0,y0,x1,y1,x2,y2,pcolor,light_texture,lx0,ly0,lx1,ly1,lx2,ly2,opac).
33411 draw_triangle(x0,y0,x2,y2,x3,y3,pcolor,light_texture,lx0,ly0,lx2,ly2,lx3,ly3,opac);
33412 #ifdef cimg_use_board
33415 l0 = light_texture((
int)(light_texture.width()/2*(1+lx0)), (int)(light_texture.height()/2*(1+ly0))),
33416 l1 = light_texture((
int)(light_texture.width()/2*(1+lx1)), (int)(light_texture.height()/2*(1+ly1))),
33417 l2 = light_texture((
int)(light_texture.width()/2*(1+lx2)), (int)(light_texture.height()/2*(1+ly2))),
33418 l3 = light_texture((
int)(light_texture.width()/2*(1+lx3)), (int)(light_texture.height()/2*(1+ly3)));
33419 board.setPenColorRGBi((
unsigned char)(color[0]),
33420 (
unsigned char)(color[1]),
33421 (
unsigned char)(color[2]),
33422 (
unsigned char)(opac*255));
33423 board.fillGouraudTriangle((
float)x0,
height()-(
float)y0,l0,
33424 (
float)x1,
height()-(
float)y1,l1,
33425 (
float)x2,
height()-(
float)y2,l2);
33426 board.fillGouraudTriangle((
float)x0,
height()-(
float)y0,l0,
33427 (
float)x2,
height()-(
float)y2,l2,
33428 (
float)x3,
height()-(
float)y3,l3);
33436 throw CImgArgumentException(_cimg_instance
33437 "draw_object3d(): Undefined texture for triangle primitive [%u].",
33438 cimg_instance,n_primitive);
33440 n0 = (
unsigned int)primitive[0],
33441 n1 = (
unsigned int)primitive[1],
33442 n2 = (
unsigned int)primitive[2],
33443 tx0 = (
unsigned int)primitive[3],
33444 ty0 = (
unsigned int)primitive[4],
33445 tx1 = (
unsigned int)primitive[5],
33446 ty1 = (
unsigned int)primitive[6],
33447 tx2 = (
unsigned int)primitive[7],
33448 ty2 = (
unsigned int)primitive[8];
33450 x0 = (int)projections(n0,0), y0 = (int)projections(n0,1),
33451 x1 = (int)projections(n1,0), y1 = (int)projections(n1,1),
33452 x2 = (int)projections(n2,0), y2 = (int)projections(n2,1);
33454 z0 = vertices(n0,2) + Z + _focale,
33455 z1 = vertices(n1,2) + Z + _focale,
33456 z2 = vertices(n2,2) + Z + _focale;
33457 switch (render_type) {
33459 draw_point(x0,y0,color.get_vector_at(tx0,ty0)._data,opac).
33460 draw_point(x1,y1,color.get_vector_at(tx1,ty1)._data,opac).
33461 draw_point(x2,y2,color.get_vector_at(tx2,ty2)._data,opac);
33462 #ifdef cimg_use_board
33464 board.setPenColorRGBi(128,128,128,(
unsigned char)(opac*255));
33465 board.drawCircle((
float)x0,
height()-(
float)y0,0);
33466 board.drawCircle((
float)x1,
height()-(
float)y1,0);
33467 board.drawCircle((
float)x2,
height()-(
float)y2,0);
33473 draw_line(zbuffer,x0,y0,z0,x1,y1,z1,color,tx0,ty0,tx1,ty1,opac).
33474 draw_line(zbuffer,x0,y0,z0,x2,y2,z2,color,tx0,ty0,tx2,ty2,opac).
33475 draw_line(zbuffer,x1,y1,z1,x2,y2,z2,color,tx1,ty1,tx2,ty2,opac);
33477 draw_line(x0,y0,z0,x1,y1,z1,color,tx0,ty0,tx1,ty1,opac).
33478 draw_line(x0,y0,z0,x2,y2,z2,color,tx0,ty0,tx2,ty2,opac).
33479 draw_line(x1,y1,z1,x2,y2,z2,color,tx1,ty1,tx2,ty2,opac);
33480 #ifdef cimg_use_board
33482 board.setPenColorRGBi(128,128,128,(
unsigned char)(opac*255));
33483 board.drawLine((
float)x0,
height()-(
float)y0,(
float)x1,
height()-(
float)y1);
33484 board.drawLine((
float)x0,
height()-(
float)y0,(
float)x2,
height()-(
float)y2);
33485 board.drawLine((
float)x1,
height()-(
float)y1,(
float)x2,
height()-(
float)y2);
33490 if (zbuffer)
draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,opac);
33491 else draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,opac);
33492 #ifdef cimg_use_board
33494 board.setPenColorRGBi(128,128,128,(
unsigned char)(opac*255));
33495 board.fillTriangle((
float)x0,
height()-(
float)y0,(
float)x1,
height()-(
float)y1,(
float)x2,
height()-(
float)y2);
33500 if (zbuffer)
draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,opac,lightprops(l));
33501 else draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,opac,lightprops(l));
33502 #ifdef cimg_use_board
33504 const float lp =
cimg::min(lightprops(l),1);
33505 board.setPenColorRGBi((
unsigned char)(128*lp),
33506 (
unsigned char)(128*lp),
33507 (
unsigned char)(128*lp),
33508 (
unsigned char)(opac*255));
33509 board.fillTriangle((
float)x0,
height()-(
float)y0,(
float)x1,
height()-(
float)y1,(
float)x2,
height()-(
float)y2);
33515 draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,lightprops(n0),lightprops(n1),lightprops(n2),opac);
33517 draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,lightprops(n0),lightprops(n1),lightprops(n2),opac);
33518 #ifdef cimg_use_board
33520 board.setPenColorRGBi(128,128,128,(
unsigned char)(opac*255));
33521 board.fillGouraudTriangle((
float)x0,
height()-(
float)y0,lightprops(n0),
33522 (
float)x1,
height()-(
float)y1,lightprops(n1),
33523 (
float)x2,
height()-(
float)y2,lightprops(n2));
33529 draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,light_texture,
33530 (
unsigned int)lightprops(n0,0),(
unsigned int)lightprops(n0,1),
33531 (
unsigned int)lightprops(n1,0),(
unsigned int)lightprops(n1,1),
33532 (
unsigned int)lightprops(n2,0),(
unsigned int)lightprops(n2,1),
33535 draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,light_texture,
33536 (
unsigned int)lightprops(n0,0),(
unsigned int)lightprops(n0,1),
33537 (
unsigned int)lightprops(n1,0),(
unsigned int)lightprops(n1,1),
33538 (
unsigned int)lightprops(n2,0),(
unsigned int)lightprops(n2,1),
33540 #ifdef cimg_use_board
33543 l0 = light_texture((
int)(light_texture.width()/2*(1+lightprops(n0,0))), (int)(light_texture.height()/2*(1+lightprops(n0,1)))),
33544 l1 = light_texture((
int)(light_texture.width()/2*(1+lightprops(n1,0))), (int)(light_texture.height()/2*(1+lightprops(n1,1)))),
33545 l2 = light_texture((
int)(light_texture.width()/2*(1+lightprops(n2,0))), (int)(light_texture.height()/2*(1+lightprops(n2,1))));
33546 board.setPenColorRGBi(128,128,128,(
unsigned char)(opac*255));
33547 board.fillGouraudTriangle((
float)x0,
height()-(
float)y0,l0,(
float)x1,
height()-(
float)y1,l1,(
float)x2,
height()-(
float)y2,l2);
33555 throw CImgArgumentException(_cimg_instance
33556 "draw_object3d(): Undefined texture for quadrangle primitive [%u].",
33557 cimg_instance,n_primitive);
33559 n0 = (
unsigned int)primitive[0],
33560 n1 = (
unsigned int)primitive[1],
33561 n2 = (
unsigned int)primitive[2],
33562 n3 = (
unsigned int)primitive[3],
33563 tx0 = (
unsigned int)primitive[4],
33564 ty0 = (
unsigned int)primitive[5],
33565 tx1 = (
unsigned int)primitive[6],
33566 ty1 = (
unsigned int)primitive[7],
33567 tx2 = (
unsigned int)primitive[8],
33568 ty2 = (
unsigned int)primitive[9],
33569 tx3 = (
unsigned int)primitive[10],
33570 ty3 = (
unsigned int)primitive[11];
33572 x0 = (int)projections(n0,0), y0 = (int)projections(n0,1),
33573 x1 = (int)projections(n1,0), y1 = (int)projections(n1,1),
33574 x2 = (int)projections(n2,0), y2 = (int)projections(n2,1),
33575 x3 = (int)projections(n3,0), y3 = (int)projections(n3,1);
33577 z0 = vertices(n0,2) + Z + _focale,
33578 z1 = vertices(n1,2) + Z + _focale,
33579 z2 = vertices(n2,2) + Z + _focale,
33580 z3 = vertices(n3,2) + Z + _focale;
33582 switch (render_type) {
33584 draw_point(x0,y0,color.get_vector_at(tx0,ty0)._data,opac).
33585 draw_point(x1,y1,color.get_vector_at(tx1,ty1)._data,opac).
33586 draw_point(x2,y2,color.get_vector_at(tx2,ty2)._data,opac).
33587 draw_point(x3,y3,color.get_vector_at(tx3,ty3)._data,opac);
33588 #ifdef cimg_use_board
33590 board.setPenColorRGBi(128,128,128,(
unsigned char)(opac*255));
33591 board.drawCircle((
float)x0,
height()-(
float)y0,0);
33592 board.drawCircle((
float)x1,
height()-(
float)y1,0);
33593 board.drawCircle((
float)x2,
height()-(
float)y2,0);
33594 board.drawCircle((
float)x3,
height()-(
float)y3,0);
33600 draw_line(zbuffer,x0,y0,z0,x1,y1,z1,color,tx0,ty0,tx1,ty1,opac).
33601 draw_line(zbuffer,x1,y1,z1,x2,y2,z2,color,tx1,ty1,tx2,ty2,opac).
33602 draw_line(zbuffer,x2,y2,z2,x3,y3,z3,color,tx2,ty2,tx3,ty3,opac).
33603 draw_line(zbuffer,x3,y3,z3,x0,y0,z0,color,tx3,ty3,tx0,ty0,opac);
33605 draw_line(x0,y0,z0,x1,y1,z1,color,tx0,ty0,tx1,ty1,opac).
33606 draw_line(x1,y1,z1,x2,y2,z2,color,tx1,ty1,tx2,ty2,opac).
33607 draw_line(x2,y2,z2,x3,y3,z3,color,tx2,ty2,tx3,ty3,opac).
33608 draw_line(x3,y3,z3,x0,y0,z0,color,tx3,ty3,tx0,ty0,opac);
33609 #ifdef cimg_use_board
33611 board.setPenColorRGBi(128,128,128,(
unsigned char)(opac*255));
33612 board.drawLine((
float)x0,
height()-(
float)y0,(
float)x1,
height()-(
float)y1);
33613 board.drawLine((
float)x1,
height()-(
float)y1,(
float)x2,
height()-(
float)y2);
33614 board.drawLine((
float)x2,
height()-(
float)y2,(
float)x3,
height()-(
float)y3);
33615 board.drawLine((
float)x3,
height()-(
float)y3,(
float)x0,
height()-(
float)y0);
33621 draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,opac).
33622 draw_triangle(zbuffer,x0,y0,z0,x2,y2,z2,x3,y3,z3,color,tx0,ty0,tx2,ty2,tx3,ty3,opac);
33624 draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,opac).
33625 draw_triangle(x0,y0,z0,x2,y2,z2,x3,y3,z3,color,tx0,ty0,tx2,ty2,tx3,ty3,opac);
33626 #ifdef cimg_use_board
33628 board.setPenColorRGBi(128,128,128,(
unsigned char)(opac*255));
33629 board.fillTriangle((
float)x0,
height()-(
float)y0,(
float)x1,
height()-(
float)y1,(
float)x2,
height()-(
float)y2);
33630 board.fillTriangle((
float)x0,
height()-(
float)y0,(
float)x2,
height()-(
float)y2,(
float)x3,
height()-(
float)y3);
33636 draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,opac,lightprops(l)).
33637 draw_triangle(zbuffer,x0,y0,z0,x2,y2,z2,x3,y3,z3,color,tx0,ty0,tx2,ty2,tx3,ty3,opac,lightprops(l));
33639 draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,opac,lightprops(l)).
33640 draw_triangle(x0,y0,z0,x2,y2,z2,x3,y3,z3,color,tx0,ty0,tx2,ty2,tx3,ty3,opac,lightprops(l));
33641 #ifdef cimg_use_board
33643 const float lp =
cimg::min(lightprops(l),1);
33644 board.setPenColorRGBi((
unsigned char)(128*lp),
33645 (
unsigned char)(128*lp),
33646 (
unsigned char)(128*lp),
33647 (
unsigned char)(opac*255));
33648 board.fillTriangle((
float)x0,
height()-(
float)y0,(
float)x1,
height()-(
float)y1,(
float)x2,
height()-(
float)y2);
33649 board.fillTriangle((
float)x0,
height()-(
float)y0,(
float)x2,
height()-(
float)y2,(
float)x3,
height()-(
float)y3);
33655 lightprop0 = lightprops(n0), lightprop1 = lightprops(n1),
33656 lightprop2 = lightprops(n2), lightprop3 = lightprops(n3);
33658 draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,lightprop0,lightprop1,lightprop2,opac).
33659 draw_triangle(zbuffer,x0,y0,z0,x2,y2,z2,x3,y3,z3,color,tx0,ty0,tx2,ty2,tx3,ty3,lightprop0,lightprop2,lightprop3,opac);
33661 draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,lightprop0,lightprop1,lightprop2,opac).
33662 draw_triangle(x0,y0,z0,x2,y2,z2,x3,y3,z3,color,tx0,ty0,tx2,ty2,tx3,ty3,lightprop0,lightprop2,lightprop3,opac);
33663 #ifdef cimg_use_board
33665 board.setPenColorRGBi(128,128,128,(
unsigned char)(opac*255));
33666 board.fillGouraudTriangle((
float)x0,
height()-(
float)y0,lightprop0,
33667 (
float)x1,
height()-(
float)y1,lightprop1,
33668 (
float)x2,
height()-(
float)y2,lightprop2);
33669 board.fillGouraudTriangle((
float)x0,
height()-(
float)y0,lightprop0,
33670 (
float)x2,
height()-(
float)y2,lightprop2,
33671 (
float)x3,
height()-(
float)y3,lightprop3);
33677 lx0 = (
unsigned int)lightprops(n0,0), ly0 = (
unsigned int)lightprops(n0,1),
33678 lx1 = (
unsigned int)lightprops(n1,0), ly1 = (
unsigned int)lightprops(n1,1),
33679 lx2 = (
unsigned int)lightprops(n2,0), ly2 = (
unsigned int)lightprops(n2,1),
33680 lx3 = (
unsigned int)lightprops(n3,0), ly3 = (
unsigned int)lightprops(n3,1);
33682 draw_triangle(zbuffer,x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,light_texture,lx0,ly0,lx1,ly1,lx2,ly2,opac).
33683 draw_triangle(zbuffer,x0,y0,z0,x2,y2,z2,x3,y3,z3,color,tx0,ty0,tx2,ty2,tx3,ty3,light_texture,lx0,ly0,lx2,ly2,lx3,ly3,opac);
33685 draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,color,tx0,ty0,tx1,ty1,tx2,ty2,light_texture,lx0,ly0,lx1,ly1,lx2,ly2,opac).
33686 draw_triangle(x0,y0,z0,x2,y2,z2,x3,y3,z3,color,tx0,ty0,tx2,ty2,tx3,ty3,light_texture,lx0,ly0,lx2,ly2,lx3,ly3,opac);
33687 #ifdef cimg_use_board
33690 l0 = light_texture((
int)(light_texture.width()/2*(1+lx0)), (int)(light_texture.height()/2*(1+ly0))),
33691 l1 = light_texture((
int)(light_texture.width()/2*(1+lx1)), (int)(light_texture.height()/2*(1+ly1))),
33692 l2 = light_texture((
int)(light_texture.width()/2*(1+lx2)), (int)(light_texture.height()/2*(1+ly2))),
33693 l3 = light_texture((
int)(light_texture.width()/2*(1+lx3)), (int)(light_texture.height()/2*(1+ly3)));
33694 board.setPenColorRGBi(128,128,128,(
unsigned char)(opac*255));
33695 board.fillGouraudTriangle((
float)x0,
height()-(
float)y0,l0,
33696 (
float)x1,
height()-(
float)y1,l1,
33697 (
float)x2,
height()-(
float)y2,l2);
33698 board.fillGouraudTriangle((
float)x0,
height()-(
float)y0,l0,
33699 (
float)x2,
height()-(
float)y2,l2,
33700 (
float)x3,
height()-(
float)y3,l3);
33725 const unsigned int feature_type=2,
unsigned int *
const XYZ=0) {
33726 return get_select(disp,feature_type,XYZ).move_to(*
this);
33731 const unsigned int feature_type=2,
unsigned int *
const XYZ=0) {
33732 return get_select(title,feature_type,XYZ).move_to(*
this);
33737 const unsigned int feature_type=2,
unsigned int *
const XYZ=0)
const {
33738 return _get_select(disp,0,feature_type,XYZ,0,0,0,
true);
33743 const unsigned int feature_type=2,
unsigned int *
const XYZ=0)
const {
33745 return _get_select(disp,title,feature_type,XYZ,0,0,0,
true);
33749 const unsigned int feature_type,
unsigned int *
const XYZ,
33750 const int origX,
const int origY,
const int origZ,
33751 const bool reset_view3d=
true)
const {
33754 disp.
assign(cimg_fitscreen(_width,_height,_depth),title?title:0,1);
33755 if (!title) disp.
set_title(
"CImg<%s> (%ux%ux%ux%u)",
pixel_type(),_width,_height,_depth,_spectrum);
33756 }
else if (title) disp.
set_title(
"%s",title);
33758 const unsigned int old_normalization = disp.
normalization();
33760 disp._normalization = 0;
33763 unsigned char foreground_color[] = { 255,255,255 }, background_color[] = { 0,0,0 };
33765 int area = 0, starting_area = 0, clicked_area = 0, phase = 0,
33766 X0 = (int)((XYZ?XYZ[0]:_width/2)%_width), Y0 = (
int)((XYZ?XYZ[1]:_height/2)%_height), Z0 = (int)((XYZ?XYZ[2]:_depth/2)%_depth),
33767 X1 =-1, Y1 = -1, Z1 = -1,
33768 X = -1, Y = -1, Z = -1, X3d = -1, Y3d = -1,
33769 oX = X, oY = Y, oZ = Z, oX3d = X3d, oY3d = -1;
33770 unsigned int old_button = 0, key = 0;
33772 bool shape_selected =
false, text_down =
false;
33773 static CImg<floatT> pose3d;
33774 static bool is_view3d =
false;
33775 if (reset_view3d) { pose3d.assign(); is_view3d =
false; }
33776 CImg<floatT> points3d, opacities3d, sel_opacities3d;
33777 CImgList<uintT> primitives3d, sel_primitives3d;
33778 CImgList<ucharT> colors3d, sel_colors3d;
33779 CImg<ucharT> visu, visu0, view3d;
33780 char text[1024] = { 0 };
33782 while (!key && !disp.
is_closed() && !shape_selected) {
33785 oX = X; oY = Y; oZ = Z;
33791 mY = my<0?-1:my*(height()+(depth()>1?depth():0))/disp.height();
33793 if (mX>=0 && mY>=0 && mX<
width() && mY<
height()) { area = 1; X = mX; Y = mY; Z = phase?Z1:Z0; }
33794 if (mX>=0 && mX<
width() && mY>=
height()) { area = 2; X = mX; Z = mY - _height; Y = phase?Y1:Y0; }
33795 if (mY>=0 && mX>=
width() && mY<
height()) { area = 3; Y = mY; Z = mX - _width; X = phase?X1:X0; }
33797 if (disp.
button()) {
if (!clicked_area) clicked_area = area; }
else clicked_area = 0;
33799 switch (key = disp.
key()) {
33804 case cimg::keyPAGEUP :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { disp.
set_wheel(1); key = 0; }
break;
33806 case cimg::keyD :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
33808 CImgDisplay::_fitscreen(3*disp.
width()/2,3*disp.
height()/2,1,128,-100,
true),
false).
33809 _is_resized =
true;
33810 disp.
set_key(key,
false); key = 0; visu0.assign();
33812 case cimg::keyC :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
33814 disp.
set_key(key,
false); key = 0; visu0.assign();
33816 case cimg::keyR :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
33817 disp.
set_fullscreen(
false).
resize(cimg_fitscreen(_width,_height,_depth),
false)._is_resized =
true;
33818 disp.
set_key(key,
false); key = 0; visu0.assign();
33820 case cimg::keyF :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
33822 disp.
set_key(key,
false); key = 0; visu0.assign();
33824 case cimg::keyV : is_view3d = !is_view3d; disp.
set_key(key,
false); key = 0; visu0.assign();
break;
33825 case cimg::keyS :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
33826 static unsigned int snap_number = 0;
33827 char filename[32] = { 0 };
33830 cimg_snprintf(filename,
sizeof(filename),cimg_appname
"_%.4u.bmp",snap_number++);
33831 if ((file=std::fopen(filename,
"r"))!=0)
cimg::fclose(file);
33834 visu.draw_text(0,0,
" Saving snapshot... ",foreground_color,background_color,1,13).display(disp);
33835 visu0.save(filename);
33836 visu.draw_text(0,0,
" Snapshot '%s' saved. ",foreground_color,background_color,1,13,filename).display(disp);
33838 disp.
set_key(key,
false); key = 0;
33841 if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
33842 static unsigned int snap_number = 0;
33843 char filename[32] = { 0 };
33846 #ifdef cimg_use_zlib
33847 cimg_snprintf(filename,
sizeof(filename),cimg_appname
"_%.4u.cimgz",snap_number++);
33849 cimg_snprintf(filename,
sizeof(filename),cimg_appname
"_%.4u.cimg",snap_number++);
33851 if ((file=std::fopen(filename,
"r"))!=0)
cimg::fclose(file);
33853 visu.draw_text(0,0,
" Saving instance... ",foreground_color,background_color,1,13).display(disp);
33855 visu.draw_text(0,0,
" Instance '%s' saved. ",foreground_color,background_color,1,13,filename).display(disp);
33856 disp.
set_key(key,
false); key = 0;
33863 mx = my = X = Y = Z = -1;
33866 case 1 :
case 2 :
case 3 :
33867 if (disp.
button()&1 && phase<2 && clicked_area==area) {
33868 if (_depth>1 && (X1!=X || Y1!=Y || Z1!=Z)) visu0.assign();
33869 X1 = X; Y1 = Y; Z1 = Z;
33871 if (!(disp.
button()&1) && phase>=2 && clicked_area!=area) {
33872 switch (starting_area) {
33873 case 1 :
if (Z1!=Z) visu0.assign(); Z1 = Z;
break;
33874 case 2 :
if (Y1!=Y) visu0.assign(); Y1 = Y;
break;
33875 case 3 :
if (X1!=X) visu0.assign(); X1 = X;
break;
33878 if (disp.
button()&2 && clicked_area==area) {
33880 if (_depth>1 && (X1!=X || Y1!=Y || Z1!=Z)) visu0.assign();
33881 X1 = X; Y1 = Y; Z1 = Z;
33883 if (_depth>1 && (X0!=X || Y0!=Y || Z0!=Z)) visu0.assign();
33884 X0 = X; Y0 = Y; Z0 = Z;
33888 oX = X = X0; oY = Y = Y0; oZ = Z = Z0; phase = area = clicked_area = starting_area = 0; visu0.assign();
33890 if (disp.
wheel()) {
33891 if (_depth>1 && !disp.is_keyCTRLLEFT() && !disp.is_keyCTRLRIGHT() && !disp.is_keySHIFTLEFT() && !disp.is_keySHIFTRIGHT() &&
33892 !disp.is_keyALT() && !disp.is_keyALTGR()) {
33895 if (phase) Z = (Z1+=disp.
wheel());
else Z = (Z0+=disp.
wheel());
33896 visu0.assign();
break;
33898 if (phase) Y = (Y1+=disp.
wheel());
else Y = (Y0+=disp.
wheel());
33899 visu0.assign();
break;
33901 if (phase) X = (X1+=disp.
wheel());
else X = (X0+=disp.
wheel());
33902 visu0.assign();
break;
33907 if ((disp.
button()&1)!=old_button) {
33910 if (area==clicked_area) {
33911 X0 = X1 = X; Y0 = Y1 = Y; Z0 = Z1 = Z; starting_area = area; ++phase;
33914 if (area==starting_area) {
33915 X1 = X; Y1 = Y; Z1 = Z; ++phase;
33916 }
else if (!(disp.
button()&1)) { oX = X = X0; oY = Y = Y0; oZ = Z = Z0; phase = 0; visu0.assign(); }
33918 case 2 : ++phase;
break;
33920 old_button = disp.
button()&1;
33925 if (is_view3d && points3d) {
33926 X3d = mx - _width*disp.
width()/(_width+(_depth>1?_depth:0));
33927 Y3d = my - _height*disp.
height()/(_height+(_depth>1?_depth:0));
33928 if (oX3d<0) { oX3d = X3d; oY3d = Y3d; }
33929 if ((disp.
button()&3)==3) { pose3d.assign(); view3d.assign(); oX3d = oY3d = X3d = Y3d = -1; }
33930 else if (disp.
button()&1 && pose3d && (oX3d!=X3d || oY3d!=Y3d)) {
33932 R = 0.45f*
cimg::min(view3d._width,view3d._height),
33934 u0 = (float)(oX3d-view3d.width()/2),
33935 v0 = (
float)(oY3d-view3d.height()/2),
33936 u1 = (
float)(X3d-view3d.width()/2),
33937 v1 = (
float)(Y3d-view3d.height()/2),
33938 n0 = (
float)std::sqrt(u0*u0+v0*v0),
33939 n1 = (float)std::sqrt(u1*u1+v1*v1),
33940 nu0 = n0>R?(u0*R/n0):u0,
33941 nv0 = n0>R?(v0*R/n0):v0,
33942 nw0 = (float)std::
sqrt(cimg::
max(0,R2-nu0*nu0-nv0*nv0)),
33943 nu1 = n1>R?(u1*R/n1):u1,
33944 nv1 = n1>R?(v1*R/n1):v1,
33945 nw1 = (float)std::
sqrt(cimg::
max(0,R2-nu1*nu1-nv1*nv1)),
33946 u = nv0*nw1 - nw0*nv1,
33947 v = nw0*nu1 - nu0*nw1,
33948 w = nv0*nu1 - nu0*nv1,
33949 n = (float)std::
sqrt(u*u+v*v+w*w),
33950 alpha = (float)std::
asin(n/R2);
33953 }
else if (disp.
button()&2 && pose3d && oY3d!=Y3d) {
33954 pose3d(3,2)-=(oY3d - Y3d)*1.5f; view3d.assign();
33956 if (disp.
wheel()) {
33957 pose3d(3,2)-=disp.
wheel()*15; view3d.assign(); disp.
set_wheel();
33959 if (disp.
button()&4 && pose3d && (oX3d!=X3d || oY3d!=Y3d)) {
33960 pose3d(3,0)-=oX3d - X3d; pose3d(3,1)-=oY3d - Y3d; view3d.assign();
33962 oX3d = X3d; oY3d = Y3d;
33964 mx = my = X = Y = Z = -1;
33969 if (!feature_type) shape_selected = phase?
true:
false;
33971 if (_depth>1) shape_selected = (phase==3)?
true:
false;
33972 else shape_selected = (phase==2)?
true:
false;
33976 if (X0<0) X0 = 0;
if (X0>=
width()) X0 =
width() - 1;
33977 if (Y0<0) Y0 = 0;
if (Y0>=
height()) Y0 =
height() - 1;
33978 if (Z0<0) Z0 = 0;
if (Z0>=
depth()) Z0 =
depth() - 1;
33979 if (X1<1) X1 = 0;
if (X1>=
width()) X1 =
width() - 1;
33980 if (Y1<0) Y1 = 0;
if (Y1>=
height()) Y1 =
height() - 1;
33981 if (Z1<0) Z1 = 0;
if (Z1>=
depth()) Z1 =
depth() - 1;
33984 if (oX!=X || oY!=Y || oZ!=Z || !visu0 || (_depth>1 && !view3d)) {
33987 CImg<Tuchar> tmp, tmp0;
33992 switch (old_normalization) {
33993 case 0 : tmp.move_to(visu0);
break;
33994 case 1 : tmp.normalize(0,255).move_to(visu0);
break;
33996 const float m = disp._min, M = disp._max;
33997 ((tmp-=m)*=255.0f/(M-m>0?M-m:1)).
move_to(visu0);
34000 if (cimg::type<T>::is_float()) (tmp.normalize(0,255)).
move_to(visu0);
34002 const float m = (float)cimg::type<T>::min(), M = (float)cimg::type<T>::max();
34003 ((tmp-=m)*=255.0f/(M-m)).
move_to(visu0);
34006 visu0.resize(disp);
34011 if (is_view3d && _depth>1 && !view3d) {
34013 _x3d = (
unsigned int)
cimg::round((
float)_width*visu0._width/(_width+_depth),1,1),
34014 _y3d = (
unsigned int)
cimg::round((
float)_height*visu0._height/(_height+_depth),1,1),
34015 x3d = _x3d>=visu0._width?visu0._width-1:_x3d,
34016 y3d = _y3d>=visu0._height?visu0._height-1:_y3d;
34017 CImg<ucharT>(1,2,1,1,64,128).
resize(visu0._width-x3d,visu0._height-y3d,1,visu0._spectrum,3).move_to(view3d);
34020 points3d.append(CImg<floatT>(8,3,1,1,
34021 0,_width-1,_width-1,0,0,_width-1,_width-1,0,
34022 0,0,_height-1,_height-1,0,0,_height-1,_height-1,
34023 0,0,0,0,_depth-1,_depth-1,_depth-1,_depth-1),
'x');
34030 colors3d.insert(12,CImg<ucharT>::vector(255,255,255));
34031 opacities3d.assign(primitives3d.width(),1,1,1,0.5f);
34033 opacities3d[0] = opacities3d[1] = opacities3d[2] = 0.8f;
34034 sel_primitives3d.assign();
34035 sel_colors3d.assign();
34036 sel_opacities3d.assign();
34038 if (feature_type==2) {
34039 points3d.append(CImg<floatT>(8,3,1,1,
34040 X0,X1,X1,X0,X0,X1,X1,X0,
34041 Y0,Y0,Y1,Y1,Y0,Y0,Y1,Y1,
34042 Z0,Z0,Z0,Z0,Z1,Z1,Z1,Z1),
'x');
34043 sel_primitives3d.assign();
34051 points3d.append(CImg<floatT>(2,3,1,1,
34057 sel_colors3d.assign(sel_primitives3d._width,CImg<ucharT>::vector(255,255,255));
34058 sel_opacities3d.assign(sel_primitives3d._width,1,1,1,0.8f);
34060 points3d.shift_object3d(-0.5f*_width,-0.5f*_height,-0.5f*_depth).resize_object3d();
34061 points3d*=0.75f*
cimg::min(view3d._width,view3d._height);
34064 if (!pose3d) CImg<floatT>(4,3,1,1, 1,0,0,0, 0,1,0,0, 0,0,1,0).
move_to(pose3d);
34065 CImg<floatT> zbuffer3d(view3d._width,view3d._height,1,1,0);
34066 const CImg<floatT> rotated_points3d = pose3d.get_crop(0,0,2,2)*points3d;
34067 if (sel_primitives3d)
34068 view3d.draw_object3d(pose3d(3,0) + 0.5f*view3d._width,
34069 pose3d(3,1) + 0.5f*view3d._height,
34071 rotated_points3d,sel_primitives3d,sel_colors3d,sel_opacities3d,
34072 2,
true,500,0,0,0,0,0,zbuffer3d);
34073 view3d.draw_object3d(pose3d(3,0) + 0.5f*view3d._width,
34074 pose3d(3,1) + 0.5f*view3d._height,
34076 rotated_points3d,primitives3d,colors3d,opacities3d,
34077 2,
true,500,0,0,0,0,0,zbuffer3d);
34078 visu0.draw_image(x3d,y3d,view3d);
34082 const int d = (_depth>1)?_depth:0;
34083 if (phase)
switch (feature_type) {
34086 x0 = (int)((X0+0.5f)*disp.
width()/(_width+d)),
34087 y0 = (int)((Y0+0.5f)*disp.
height()/(_height+d)),
34088 x1 = (int)((X1+0.5f)*disp.
width()/(_width+d)),
34089 y1 = (int)((Y1+0.5f)*disp.
height()/(_height+d));
34090 visu.draw_arrow(x0,y0,x1,y1,background_color,0.9f,30,5,0x55555555).
34091 draw_arrow(x0,y0,x1,y1,foreground_color,0.9f,30,5,0xAAAAAAAA);
34094 zx0 = (int)((_width+Z0+0.5f)*disp.
width()/(_width+d)),
34095 zx1 = (int)((_width+Z1+0.5f)*disp.
width()/(_width+d)),
34096 zy0 = (int)((_height+Z0+0.5f)*disp.
height()/(_height+d)),
34097 zy1 = (int)((_height+Z1+0.5f)*disp.
height()/(_height+d));
34098 visu.draw_arrow(zx0,y0,zx1,y1,foreground_color,0.9f,30,5,0x55555555).
34099 draw_arrow(x0,zy0,x1,zy1,foreground_color,0.9f,30,5,0x55555555).
34100 draw_arrow(zx0,y0,zx1,y1,foreground_color,0.9f,30,5,0xAAAAAAAA).
34101 draw_arrow(x0,zy0,x1,zy1,foreground_color,0.9f,30,5,0xAAAAAAAA);
34106 x0 = (X0<X1?X0:X1)*disp.
width()/(_width+d),
34107 y0 = (Y0<Y1?Y0:Y1)*disp.
height()/(_height+d),
34108 x1 = ((X0<X1?X1:X0)+1)*disp.
width()/(_width+d)-1,
34109 y1 = ((Y0<Y1?Y1:Y0)+1)*disp.
height()/(_height+d)-1;
34110 visu.draw_rectangle(x0,y0,x1,y1,background_color,0.2f).draw_rectangle(x0,y0,x1,y1,foreground_color,0.6f,0x55555555);
34113 zx0 = (int)((_width+(Z0<Z1?Z0:Z1))*disp.
width()/(_width+d)),
34114 zy0 = (int)((_height+(Z0<Z1?Z0:Z1))*disp.
height()/(_height+d)),
34115 zx1 = (int)((_width+(Z0<Z1?Z1:Z0)+1)*disp.
width()/(_width+d))-1,
34116 zy1 = (int)((_height+(Z0<Z1?Z1:Z0)+1)*disp.
height()/(_height+d))-1;
34117 visu.draw_rectangle(zx0,y0,zx1,y1,background_color,0.2f).draw_rectangle(zx0,y0,zx1,y1,foreground_color,0.6f,0x55555555).
34118 draw_rectangle(x0,zy0,x1,zy1,background_color,0.2f).draw_rectangle(x0,zy0,x1,zy1,foreground_color,0.6f,0x55555555);
34123 x0 = X0*disp.
width()/(_width+d),
34124 y0 = Y0*disp.
height()/(_height+d),
34125 x1 = X1*disp.
width()/(_width+d)-1,
34126 y1 = Y1*disp.
height()/(_height+d)-1;
34127 visu.draw_ellipse(x0,y0,(
float)cimg::abs(x1-x0),(
float)cimg::abs(y1-y0),0,background_color,0.2f).
34128 draw_ellipse(x0,y0,(
float)cimg::abs(x1-x0),(
float)cimg::abs(y1-y0),0,foreground_color,0.6f,0x55555555).
34132 zx0 = (int)((_width+Z0)*disp.
width()/(_width+d)),
34133 zy0 = (int)((_height+Z0)*disp.
height()/(_height+d)),
34134 zx1 = (int)((_width+Z1+1)*disp.
width()/(_width+d))-1,
34135 zy1 = (int)((_height+Z1+1)*disp.
height()/(_height+d))-1;
34136 visu.draw_ellipse(zx0,y0,(
float)cimg::abs(zx1-zx0),(
float)cimg::abs(y1-y0),0,background_color,0.2f).
34137 draw_ellipse(zx0,y0,(
float)cimg::abs(zx1-zx0),(
float)cimg::abs(y1-y0),0,foreground_color,0.6f,0x55555555).
34139 draw_ellipse(x0,zy0,(
float)cimg::abs(x1-x0),(
float)cimg::abs(zy1-zy0),0,background_color,0.2f).
34140 draw_ellipse(x0,zy0,(
float)cimg::abs(x1-x0),(
float)cimg::abs(zy1-zy0),0,foreground_color,0.6f,0x55555555).
34146 x0 = X*disp.
width()/(_width+d),
34147 y0 = Y*disp.
height()/(_height+d),
34148 x1 = (X+1)*disp.
width()/(_width+d)-1,
34149 y1 = (Y+1)*disp.
height()/(_height+d)-1,
34150 zx0 = (Z+_width)*disp.
width()/(_width+d),
34151 zx1 = (Z+_width+1)*disp.
width()/(_width+d),
34152 zy0 = (Z+_height)*disp.
height()/(_height+d),
34153 zy1 = (Z+_height+1)*disp.
height()/(_height+d);
34155 if (x1-x0>=4 && y1-y0>=4) visu.draw_rectangle(x0,y0,x1,y1,background_color,0.2f).
34159 if (y1-y0>=4 && zx1-zx0>=4) visu.draw_rectangle(zx0,y0,zx1,y1,background_color,0.2f).
34161 if (x1-x0>=4 && zy1-zy0>=4) visu.draw_rectangle(x0,zy0,x1,zy1,background_color,0.2f).
34166 if (my>=0 && my<13) text_down =
true;
else if (my>=visu.height()-13) text_down =
false;
34167 if (!feature_type || !phase) {
34169 if (_depth>1) cimg_snprintf(text,
sizeof(text),
" Point (%d,%d,%d) = [ ",origX+X,origY+Y,origZ+Z);
34170 else cimg_snprintf(text,
sizeof(text),
" Point (%d,%d) = [ ",origX+X,origY+Y);
34171 char *ctext = text + std::strlen(text), *
const ltext = text + 512;
34172 for (
unsigned int c = 0; c<_spectrum && ctext<ltext; ++c) {
34173 cimg_snprintf(ctext,
sizeof(text)/2,cimg::type<T>::format(),cimg::type<T>::format((*
this)(X,Y,Z,c)));
34174 ctext = text + std::strlen(text);
34175 *(ctext++) =
' '; *ctext = 0;
34177 std::strcpy(text + std::strlen(text),
"] ");
34179 }
else switch (feature_type) {
34181 const double dX = (double)(X0 - X1), dY = (double)(Y0 - Y1), dZ = (double)(Z0 - Z1), norm = std::sqrt(dX*dX+dY*dY+dZ*dZ);
34182 if (_depth>1) cimg_snprintf(text,
sizeof(text),
" Vect (%d,%d,%d)-(%d,%d,%d), Norm = %g ",
34183 origX+X0,origY+Y0,origZ+Z0,origX+X1,origY+Y1,origZ+Z1,norm);
34184 else cimg_snprintf(text,
sizeof(text),
" Vect (%d,%d)-(%d,%d), Norm = %g ",
34185 origX+X0,origY+Y0,origX+X1,origY+Y1,norm);
34188 if (_depth>1) cimg_snprintf(text,
sizeof(text),
" Box (%d,%d,%d)-(%d,%d,%d), Size = (%d,%d,%d) ",
34189 origX+(X0<X1?X0:X1),origY+(Y0<Y1?Y0:Y1),origZ+(Z0<Z1?Z0:Z1),
34190 origX+(X0<X1?X1:X0),origY+(Y0<Y1?Y1:Y0),origZ+(Z0<Z1?Z1:Z0),
34191 1+cimg::abs(X0-X1),1+cimg::abs(Y0-Y1),1+cimg::abs(Z0-Z1));
34192 else cimg_snprintf(text,
sizeof(text),
" Box (%d,%d)-(%d,%d), Size = (%d,%d) ",
34193 origX+(X0<X1?X0:X1),origY+(Y0<Y1?Y0:Y1),origX+(X0<X1?X1:X0),origY+(Y0<Y1?Y1:Y0),
34194 1+cimg::abs(X0-X1),1+cimg::abs(Y0-Y1));
34197 if (_depth>1) cimg_snprintf(text,
sizeof(text),
" Ellipse (%d,%d,%d)-(%d,%d,%d), Radii = (%d,%d,%d) ",
34198 origX+X0,origY+Y0,origZ+Z0,origX+X1,origY+Y1,origZ+Z1,
34199 1+cimg::abs(X0-X1),1+cimg::abs(Y0-Y1),1+cimg::abs(Z0-Z1));
34200 else cimg_snprintf(text,
sizeof(text),
" Ellipse (%d,%d)-(%d,%d), Radii = (%d,%d) ",
34201 origX+X0,origY+Y0,origX+X1,origY+Y1,1+cimg::abs(X0-X1),1+cimg::abs(Y0-Y1));
34203 if (phase || (mx>=0 && my>=0)) visu.draw_text(0,text_down?visu.height()-13:0,text,foreground_color,background_color,0.7f,13);
34205 }
else if (!shape_selected) disp.
wait();
34206 if (disp.
is_resized()) { disp.
resize(
false)._is_resized =
false; old_is_resized =
true; visu0.assign(); }
34210 CImg<intT> res(1,feature_type==0?3:6,1,1,-1);
34211 if (XYZ) { XYZ[0] = (
unsigned int)X0; XYZ[1] = (
unsigned int)Y0; XYZ[2] = (
unsigned int)Z0; }
34212 if (shape_selected) {
34213 if (feature_type==2) {
34218 if (X1<0 || Y1<0 || Z1<0) X0 = Y0 = Z0 = X1 = Y1 = Z1 = -1;
34219 switch (feature_type) {
34220 case 1 :
case 2 : res[0] = X0; res[1] = Y0; res[2] = Z0; res[3] = X1; res[4] = Y1; res[5] = Z1;
break;
34222 default : res[0] = X0; res[1] = Y0; res[2] = Z0;
34226 disp._normalization = old_normalization;
34227 disp._is_resized = old_is_resized;
34228 if (key!=~0U) disp.
set_key(key);
34234 const unsigned int plot_type=1,
const unsigned int vertex_type=1,
34235 const char *
const labelx=0,
const double xmin=0,
const double xmax=0,
34236 const char *
const labely=0,
const double ymin=0,
const double ymax=0)
const {
34239 "select_graph(): Empty instance.",
34242 const unsigned long siz = (
unsigned long)_width*_height*_depth;
34243 const unsigned int old_normalization = disp.
normalization();
34246 double nymin = ymin, nymax = ymax, nxmin = xmin, nxmax = xmax;
34247 if (nymin==nymax) { nymin = (Tfloat)
min_max(nymax);
const double dy = nymax - nymin; nymin-=dy/20; nymax+=dy/20; }
34248 if (nymin==nymax) { --nymin; ++nymax; }
34249 if (nxmin==nxmax && nxmin==0) { nxmin = 0; nxmax = siz - 1.0; }
34251 const unsigned char black[] = { 0, 0, 0 }, white[] = { 255, 255, 255 }, gray[] = { 220, 220, 220 };
34252 const unsigned char gray2[] = { 110, 110, 110 }, ngray[] = { 35, 35, 35 };
34253 static unsigned int odimv = 0;
34255 if (odimv!=_spectrum) {
34258 if (_spectrum==1) { colormap[0] = colormap[1] = 120; colormap[2] = 200; }
34260 colormap(0,0) = 220; colormap(1,0) = 10; colormap(2,0) = 10;
34261 if (_spectrum>1) { colormap(0,1) = 10; colormap(1,1) = 220; colormap(2,1) = 10; }
34262 if (_spectrum>2) { colormap(0,2) = 10; colormap(1,2) = 10; colormap(2,2) = 220; }
34267 int x0 = -1, x1 = -1, y0 = -1, y1 = -1, omouse_x = -2, omouse_y = -2;
34268 const unsigned int one = plot_type==3?0:1;
34269 unsigned int okey = 0, obutton = 0;
34270 char message[1024] = { 0 };
34271 CImg_3x3(I,
unsigned char);
34273 for (
bool selected =
false; !selected && !disp.
is_closed() && !okey && !disp.
wheel(); ) {
34275 const unsigned int key = disp.
key(), button = disp.
button();
34279 visu0.assign(disp.
width(),disp.
height(),1,3,220);
34280 const int gdimx = disp.
width() - 32, gdimy = disp.
height() - 32;
34281 if (gdimx>0 && gdimy>0) {
34282 graph.assign(gdimx,gdimy,1,3,255);
34283 if (siz<32) {
if (siz>1) graph.draw_grid(gdimx/(
float)(siz - one),gdimy/(
float)(siz - one),0,0,
false,
true,black,0.2f,0x33333333,0x33333333); }
34284 else graph.draw_grid(-10,-10,0,0,
false,
true,black,0.2f,0x33333333,0x33333333);
34285 cimg_forC(*
this,c) graph.draw_graph(
get_shared_channel(c),&colormap(0,c),(plot_type!=3 || _spectrum==1)?1:0.6f,
34286 plot_type,vertex_type,nymax,nymin);
34288 axes.assign(gdimx,gdimy,1,1,0);
34290 dx = (float)cimg::abs(nxmax-nxmin), dy = (float)cimg::abs(nymax-nymin),
34291 px = (float)std::pow(10.0,(
int)std::log10(dx?dx:1)-2.0),
34292 py = (float)std::pow(10.0,(
int)std::log10(dy?dy:1)-2.0);
34294 seqx = dx<=0?CImg<Tdouble>::vector(nxmin):
CImg<Tdouble>::sequence(1 + gdimx/60,nxmin,one?nxmax:nxmin+(nxmax-nxmin)*(siz+1)/siz).round(px),
34297 const bool allow_zero = (nxmin*nxmax>0) || (nymin*nymax>0);
34298 axes.draw_axes(seqx,seqy,white,1,~0U,~0U,13,allow_zero);
34299 if (nymin>0) axes.draw_axis(seqx,gdimy-1,gray,1,~0U,13,allow_zero);
34300 if (nymax<0) axes.draw_axis(seqx,0,gray,1,~0U,13,allow_zero);
34301 if (nxmin>0) axes.draw_axis(0,seqy,gray,1,~0U,13,allow_zero);
34302 if (nxmax<0) axes.draw_axis(gdimx-1,seqy,gray,1,~0U,13,allow_zero);
34304 cimg_for3x3(axes,x,y,0,0,I,
unsigned char)
34306 if (Icc==255) cimg_forC(graph,c) graph(x,y,c) = 0;
34307 else cimg_forC(graph,c) graph(x,y,c) = (
unsigned char)(2*graph(x,y,c)/3);
34309 else if (Ipc || Inc || Icp || Icn || Ipp || Inn || Ipn || Inp) cimg_forC(graph,c) graph(x,y,c) = (graph(x,y,c)+511)/3;
34311 visu0.draw_image(16,16,graph);
34312 visu0.draw_line(15,15,16+gdimx,15,gray2).draw_line(16+gdimx,15,16+gdimx,16+gdimy,gray2).
34313 draw_line(16+gdimx,16+gdimy,15,16+gdimy,white).draw_line(15,16+gdimy,15,15,white);
34314 }
else graph.assign();
34315 text.assign().draw_text(0,0,labelx?labelx:
"X-axis",white,ngray,1,13).resize(-100,-100,1,3);
34316 visu0.draw_image((visu0.width()-text.width())/2,visu0.height()-14,~text);
34317 text.assign().draw_text(0,0,labely?labely:
"Y-axis",white,ngray,1,13).rotate(-90).resize(-100,-100,1,3);
34318 visu0.draw_image(1,(visu0.height()-text.height())/2,~text);
34324 visu.assign(visu0);
34325 if (graph && x0>=0 && x1>=0) {
34327 nx0 = x0<=x1?x0:x1,
34328 nx1 = x0<=x1?x1:x0,
34329 ny0 = y0<=y1?y0:y1,
34330 ny1 = y0<=y1?y1:y0,
34331 sx0 = 16 + nx0*(visu.width()-32)/
cimg::max(1U,siz-one),
34332 sx1 = 15 + (nx1+1)*(visu.width()-32)/
cimg::max(1U,siz-one),
34335 if (y0>=0 && y1>=0)
34336 visu.draw_rectangle(sx0,sy0,sx1,sy1,gray,0.5f).draw_rectangle(sx0,sy0,sx1,sy1,black,0.5f,0xCCCCCCCCU);
34337 else visu.draw_rectangle(sx0,0,sx1,visu.height()-17,gray,0.5f).
34338 draw_line(sx0,16,sx0,visu.height()-17,black,0.5f,0xCCCCCCCCU).
34339 draw_line(sx1,16,sx1,visu.height()-17,black,0.5f,0xCCCCCCCCU);
34341 if (mouse_x>=16 && mouse_y>=16 && mouse_x<visu.width()-16 && mouse_y<visu.height()-16) {
34342 if (graph) visu.draw_line(mouse_x,16,mouse_x,visu.height()-17,black,0.5f,0x55555555U);
34343 const unsigned int x = (
unsigned int)
cimg::round((mouse_x-16.0f)*(siz-one)/(disp.
width()-32),1,one?0:-1);
34344 const double cx = nxmin + x*(nxmax-nxmin)/
cimg::max(1U,siz-1);
34346 cimg_snprintf(message,
sizeof(message),
"Value[%u:%g] = ( %g %g %g ... %g %g %g )",x,cx,
34347 (
double)(*
this)(x,0,0,0),(
double)(*
this)(x,0,0,1),(
double)(*
this)(x,0,0,2),
34348 (
double)(*
this)(x,0,0,_spectrum-4),(
double)(*
this)(x,0,0,_spectrum-3),(
double)(*
this)(x,0,0,_spectrum-1));
34350 cimg_snprintf(message,
sizeof(message),
"Value[%u:%g] = ( ",x,cx);
34351 cimg_forC(*
this,c) std::sprintf(message + std::strlen(message),
"%g ",(
double)(*
this)(x,0,0,c));
34352 std::sprintf(message + std::strlen(message),
")");
34354 if (x0>=0 && x1>=0) {
34356 nx0 = x0<=x1?x0:x1,
34357 nx1 = x0<=x1?x1:x0,
34358 ny0 = y0<=y1?y0:y1,
34359 ny1 = y0<=y1?y1:y0;
34361 cx0 = nxmin + nx0*(nxmax-nxmin)/
cimg::max(1U,siz-1),
34362 cx1 = nxmin + (nx1+one)*(nxmax-nxmin)/
cimg::max(1U,siz-1),
34363 cy0 = nymax - ny0*(nymax-nymin)/(visu._height-32),
34364 cy1 = nymax - ny1*(nymax-nymin)/(visu._height-32);
34365 if (y0>=0 && y1>=0)
34366 std::sprintf(message + std::strlen(message),
" - Range ( %u:%g, %g ) - ( %u:%g, %g )",x0,cx0,cy0,x1+one,cx1,cy1);
34368 std::sprintf(message + std::strlen(message),
" - Range [ %u:%g - %u:%g ]",x0,cx0,x1+one,cx1);
34370 text.assign().draw_text(0,0,message,white,ngray,1,13).resize(-100,-100,1,3);
34371 visu.draw_image((visu.width()-text.width())/2,1,~text);
34373 visu.display(disp);
34377 switch (okey = key) {
34382 case cimg::keyD :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
34384 CImgDisplay::_fitscreen(3*disp.
width()/2,3*disp.
height()/2,1,128,-100,
true),
false).
34385 _is_resized =
true;
34386 disp.
set_key(key,
false); okey = 0;
34388 case cimg::keyC :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
34390 disp.
set_key(key,
false); okey = 0;
34392 case cimg::keyR :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
34394 disp.
set_key(key,
false); okey = 0;
34396 case cimg::keyF :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
34398 disp.
set_key(key,
false); okey = 0;
34400 case cimg::keyS :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
34401 static unsigned int snap_number = 0;
34402 if (visu || visu0) {
34404 char filename[32] = { 0 };
34407 cimg_snprintf(filename,
sizeof(filename),cimg_appname
"_%.4u.bmp",snap_number++);
34408 if ((file=std::fopen(filename,
"r"))!=0)
cimg::fclose(file);
34410 (+screen).
draw_text(0,0,
" Saving snapshot... ",black,gray,1,13).display(disp);
34411 screen.save(filename);
34412 screen.draw_text(0,0,
" Snapshot '%s' saved. ",black,gray,1,13,filename).display(disp);
34414 disp.
set_key(key,
false); okey = 0;
34416 case cimg::keyO :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
34417 static unsigned int snap_number = 0;
34418 if (visu || visu0) {
34420 char filename[32] = { 0 };
34423 #ifdef cimg_use_zlib
34424 cimg_snprintf(filename,
sizeof(filename),cimg_appname
"_%.4u.cimgz",snap_number++);
34426 cimg_snprintf(filename,
sizeof(filename),cimg_appname
"_%.4u.cimg",snap_number++);
34428 if ((file=std::fopen(filename,
"r"))!=0)
cimg::fclose(file);
34430 (+screen).
draw_text(0,0,
" Saving instance... ",black,gray,1,13).display(disp);
34432 screen.draw_text(0,0,
" Instance '%s' saved. ",black,gray,1,13,filename).display(disp);
34434 disp.
set_key(key,
false); okey = 0;
34439 if (obutton!=button || omouse_x!=mouse_x || omouse_y!=mouse_y) {
34443 mx = (mouse_x -16)*(
int)(siz-one)/(disp.
width()-32),
34444 cx = mx<0?0:(mx>=(
int)(siz-one)?(
int)(siz-1-one):mx),
34446 cy = my<=0?0:(my>=(disp.
height()-32)?(disp.
height()-32):my);
34448 if (!obutton) { x0 = cx; y0 = -1; }
else { x1 = cx; y1 = -1; }
34450 else if (button&2) {
34451 if (!obutton) { x0 = cx; y0 = cy; }
else { x1 = cx; y1 = cy; }
34453 else if (obutton) { x1 = x1>=0?cx:-1; y1 = y1>=0?cy:-1; selected =
true; }
34454 }
else if (!button && obutton) selected =
true;
34455 obutton = button; omouse_x = mouse_x; omouse_y = mouse_y;
34458 if (visu && visu0) disp.
wait();
34461 disp._normalization = old_normalization;
34465 return CImg<intT>(4,1,1,1,x0,y0,x1>=0?x1+(int)one:-1,y1);
34477 "load(): Specified filename is (null).",
34481 char filename_local[1024] = { 0 };
34483 std::remove(filename_local);
34491 #ifdef cimg_load_plugin
34492 cimg_load_plugin(filename);
34494 #ifdef cimg_load_plugin1
34495 cimg_load_plugin1(filename);
34497 #ifdef cimg_load_plugin2
34498 cimg_load_plugin2(filename);
34500 #ifdef cimg_load_plugin3
34501 cimg_load_plugin3(filename);
34503 #ifdef cimg_load_plugin4
34504 cimg_load_plugin4(filename);
34506 #ifdef cimg_load_plugin5
34507 cimg_load_plugin5(filename);
34509 #ifdef cimg_load_plugin6
34510 cimg_load_plugin6(filename);
34512 #ifdef cimg_load_plugin7
34513 cimg_load_plugin7(filename);
34515 #ifdef cimg_load_plugin8
34516 cimg_load_plugin8(filename);
34593 std::FILE *file = 0;
34599 "load(): Failed to open file '%s'.",
34623 "load(): Failed to recognize format of file '%s'.",
34643 return _load_ascii(0,filename);
34653 return _load_ascii(file,0);
34661 CImg<T>& _load_ascii(std::FILE *
const file,
const char *
const filename) {
34662 if (!file && !filename)
34664 "load_ascii(): Specified filename is (null).",
34667 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"rb");
34668 char line[256] = { 0 };
34669 int err = std::fscanf(nfile,
"%255[^\n]",line);
34670 unsigned int dx = 0, dy = 1, dz = 1, dc = 1;
34671 std::sscanf(line,
"%u%*c%u%*c%u%*c%u",&dx,&dy,&dz,&dc);
34672 err = std::fscanf(nfile,
"%*[^0-9.eE+-]");
34673 if (!dx || !dy || !dz || !dc) {
34675 throw CImgIOException(_cimg_instance
34676 "load_ascii(): Invalid ascii header in file '%s', image dimensions are set to (%u,%u,%u,%u).",
34678 filename?filename:
"(FILE*)",dx,dy,dz,dc);
34681 const unsigned long siz =
size();
34682 unsigned long off = 0;
34685 for (err = 1, off = 0; off<siz && err==1; ++off) {
34686 err = std::fscanf(nfile,
"%lf%*[^0-9.eE+-]",&val);
34691 "load_ascii(): Only %lu/%lu values read from file '%s'.",
34693 off-1,siz,filename?filename:
"(FILE*)");
34704 return _load_dlm(0,filename);
34714 return _load_dlm(file,0);
34722 CImg<T>& _load_dlm(std::FILE *
const file,
const char *
const filename) {
34723 if (!file && !filename)
34725 "load_dlm(): Specified filename is (null).",
34728 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"r");
34729 char delimiter[256] = { 0 }, tmp[256] = { 0 };
34730 unsigned int cdx = 0, dx = 0, dy = 0;
34734 while ((err = std::fscanf(nfile,
"%lf%255[^0-9.+-]",&val,delimiter))>0) {
34735 if (err>0) (*this)(cdx++,dy) = (T)val;
34736 if (cdx>=_width)
resize(3*_width/2,_height,1,1,0);
34738 if (!std::sscanf(delimiter,"%255[^\n]%c",tmp,&c) || c=='\n') {
34740 if (++dy>=_height)
resize(_width,3*_height/2,1,1,0);
34744 if (cdx && err==1) { dx = cdx; ++dy; }
34747 throw CImgIOException(_cimg_instance
34748 "load_dlm(): Invalid DLM file '%s'.",
34750 filename?filename:
"(FILE*)");
34762 return _load_bmp(0,filename);
34772 return _load_bmp(file,0);
34780 CImg<T>& _load_bmp(std::FILE *
const file,
const char *
const filename) {
34781 if (!file && !filename)
34783 "load_bmp(): Specified filename is (null).",
34786 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"rb");
34787 unsigned char header[64] = { 0 };
34789 if (*header!=
'B' || header[1]!=
'M') {
34791 throw CImgIOException(_cimg_instance
34792 "load_bmp(): Invalid BMP file '%s'.",
34794 filename?filename:
"(FILE*)");
34799 file_size = header[0x02] + (header[0x03]<<8) + (header[0x04]<<16) + (header[0x05]<<24),
34800 offset = header[0x0A] + (header[0x0B]<<8) + (header[0x0C]<<16) + (header[0x0D]<<24),
34801 dx = header[0x12] + (header[0x13]<<8) + (header[0x14]<<16) + (header[0x15]<<24),
34802 dy = header[0x16] + (header[0x17]<<8) + (header[0x18]<<16) + (header[0x19]<<24),
34803 compression = header[0x1E] + (header[0x1F]<<8) + (header[0x20]<<16) + (header[0x21]<<24),
34804 nb_colors = header[0x2E] + (header[0x2F]<<8) + (header[0x30]<<16) + (header[0x31]<<24),
34805 bpp = header[0x1C] + (header[0x1D]<<8);
34807 if (!file_size || file_size==offset) {
34808 std::fseek(nfile,0,SEEK_END);
34809 file_size = (int)std::ftell(nfile);
34810 std::fseek(nfile,54,SEEK_SET);
34814 cimg_iobuffer = 12*1024*1024,
34815 dx_bytes = (bpp==1)?(dx/8+(dx%8?1:0)):((bpp==4)?(dx/2+(dx%2?1:0)):(dx*bpp/8)),
34816 align_bytes = (4-dx_bytes%4)%4,
34817 buf_size =
cimg::min(cimg::abs(dy)*(dx_bytes + align_bytes),file_size - offset);
34819 CImg<intT> colormap;
34820 if (bpp<16) {
if (!nb_colors) nb_colors = 1<<bpp; }
else nb_colors = 0;
34821 if (nb_colors) { colormap.assign(nb_colors);
cimg::fread(colormap._data,nb_colors,nfile); }
34822 const int xoffset = offset - 54 - 4*nb_colors;
34823 if (xoffset>0) std::fseek(nfile,xoffset,SEEK_CUR);
34825 CImg<ucharT> buffer;
34826 if (buf_size<cimg_iobuffer) { buffer.assign(buf_size);
cimg::fread(buffer._data,buf_size,nfile); }
34827 else buffer.assign(dx_bytes + align_bytes);
34828 unsigned char *ptrs = buffer;
34833 throw CImgIOException(_cimg_instance
34834 "load_bmp(): Unable to load compressed data from '(*FILE)' inputs.",
34843 assign(dx,cimg::abs(dy),1,3);
34846 for (
int y =
height()-1; y>=0; --y) {
34847 if (buf_size>=cimg_iobuffer) {
cimg::fread(ptrs=buffer._data,dx_bytes,nfile); std::fseek(nfile,align_bytes,SEEK_CUR); }
34848 unsigned char mask = 0x80, val = 0;
34849 cimg_forX(*
this,x) {
34850 if (mask==0x80) val = *(ptrs++);
34851 const unsigned char *col = (
unsigned char*)(colormap._data + (val&mask?1:0));
34852 (*this)(x,y,2) = (T)*(col++);
34853 (*this)(x,y,1) = (T)*(col++);
34854 (*this)(x,y,0) = (T)*(col++);
34861 for (
int y =
height()-1; y>=0; --y) {
34862 if (buf_size>=cimg_iobuffer) {
cimg::fread(ptrs=buffer._data,dx_bytes,nfile); std::fseek(nfile,align_bytes,SEEK_CUR); }
34863 unsigned char mask = 0xF0, val = 0;
34864 cimg_forX(*
this,x) {
34865 if (mask==0xF0) val = *(ptrs++);
34866 const unsigned char color = (
unsigned char)((mask<16)?(val&mask):((val&mask)>>4));
34867 const unsigned char *col = (
unsigned char*)(colormap._data + color);
34868 (*this)(x,y,2) = (T)*(col++);
34869 (*this)(x,y,1) = (T)*(col++);
34870 (*this)(x,y,0) = (T)*(col++);
34877 for (
int y =
height()-1; y>=0; --y) {
34878 if (buf_size>=cimg_iobuffer) {
cimg::fread(ptrs=buffer._data,dx_bytes,nfile); std::fseek(nfile,align_bytes,SEEK_CUR); }
34879 cimg_forX(*
this,x) {
34880 const unsigned char *col = (
unsigned char*)(colormap._data + *(ptrs++));
34881 (*this)(x,y,2) = (T)*(col++);
34882 (*this)(x,y,1) = (T)*(col++);
34883 (*this)(x,y,0) = (T)*(col++);
34889 for (
int y =
height()-1; y>=0; --y) {
34890 if (buf_size>=cimg_iobuffer) {
cimg::fread(ptrs=buffer._data,dx_bytes,nfile); std::fseek(nfile,align_bytes,SEEK_CUR); }
34891 cimg_forX(*
this,x) {
34892 const unsigned char c1 = *(ptrs++), c2 = *(ptrs++);
34893 const unsigned short col = (
unsigned short)(c1|(c2<<8));
34894 (*this)(x,y,2) = (T)(col&0x1F);
34895 (*this)(x,y,1) = (T)((col>>5)&0x1F);
34896 (*this)(x,y,0) = (T)((col>>10)&0x1F);
34902 for (
int y =
height()-1; y>=0; --y) {
34903 if (buf_size>=cimg_iobuffer) {
cimg::fread(ptrs=buffer._data,dx_bytes,nfile); std::fseek(nfile,align_bytes,SEEK_CUR); }
34904 cimg_forX(*
this,x) {
34905 (*this)(x,y,2) = (T)*(ptrs++);
34906 (*this)(x,y,1) = (T)*(ptrs++);
34907 (*this)(x,y,0) = (T)*(ptrs++);
34913 for (
int y =
height()-1; y>=0; --y) {
34914 if (buf_size>=cimg_iobuffer) {
cimg::fread(ptrs=buffer._data,dx_bytes,nfile); std::fseek(nfile,align_bytes,SEEK_CUR); }
34915 cimg_forX(*
this,x) {
34916 (*this)(x,y,2) = (T)*(ptrs++);
34917 (*this)(x,y,1) = (T)*(ptrs++);
34918 (*this)(x,y,0) = (T)*(ptrs++);
34935 return _load_jpeg(0,filename);
34945 return _load_jpeg(file,0);
34954 #ifdef cimg_use_jpeg
34955 struct _cimg_error_mgr {
34956 struct jpeg_error_mgr original;
34957 jmp_buf setjmp_buffer;
34958 char message[JMSG_LENGTH_MAX];
34961 typedef struct _cimg_error_mgr *_cimg_error_ptr;
34963 METHODDEF(
void) _cimg_jpeg_error_exit(j_common_ptr cinfo) {
34964 _cimg_error_ptr c_err = (_cimg_error_ptr) cinfo->err;
34965 (*cinfo->err->format_message)(cinfo,c_err->message);
34966 jpeg_destroy(cinfo);
34967 longjmp(c_err->setjmp_buffer,1);
34971 CImg<T>& _load_jpeg(std::FILE *
const file,
const char *
const filename) {
34972 if (!file && !filename)
34973 throw CImgArgumentException(_cimg_instance
34974 "load_jpeg(): Specified filename is (null).",
34977 #ifndef cimg_use_jpeg
34979 throw CImgIOException(_cimg_instance
34980 "load_jpeg(): Unable to load data from '(FILE*)' unless libjpeg is enabled.",
34985 struct jpeg_decompress_struct cinfo;
34986 struct _cimg_error_mgr jerr;
34987 cinfo.err = jpeg_std_error(&jerr.original);
34988 jerr.original.error_exit = _cimg_jpeg_error_exit;
34990 if (setjmp(jerr.setjmp_buffer)) {
34991 throw CImgIOException(_cimg_instance
34992 "load_jpeg(): Error message returned by libjpeg: %s.",
34993 cimg_instance,jerr.message);
34996 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"rb");
34997 jpeg_create_decompress(&cinfo);
34998 jpeg_stdio_src(&cinfo,nfile);
34999 jpeg_read_header(&cinfo,TRUE);
35000 jpeg_start_decompress(&cinfo);
35002 if (cinfo.output_components!=1 && cinfo.output_components!=3 && cinfo.output_components!=4) {
35005 throw CImgIOException(_cimg_instance
35006 "load_jpeg(): Failed to load JPEG data from file '%s'.",
35007 cimg_instance,filename?filename:
"(FILE*)");
35009 CImg<ucharT> buffer(cinfo.output_width*cinfo.output_components);
35010 JSAMPROW row_pointer[1];
35011 assign(cinfo.output_width,cinfo.output_height,1,cinfo.output_components);
35012 T *ptr_r = _data, *ptr_g = _data + 1UL*_width*_height, *ptr_b = _data + 2UL*_width*_height, *ptr_a = _data + 3UL*_width*_height;
35013 while (cinfo.output_scanline<cinfo.output_height) {
35014 *row_pointer = buffer._data;
35015 if (jpeg_read_scanlines(&cinfo,row_pointer,1)!=1) {
35017 "load_jpeg(): Incomplete data in file '%s'.",
35018 cimg_instance,filename?filename:
"(FILE*)");
35021 const unsigned char *ptrs = buffer._data;
35022 switch (_spectrum) {
35024 cimg_forX(*
this,x) *(ptr_r++) = (T)*(ptrs++);
35027 cimg_forX(*
this,x) {
35028 *(ptr_r++) = (T)*(ptrs++);
35029 *(ptr_g++) = (T)*(ptrs++);
35030 *(ptr_b++) = (T)*(ptrs++);
35034 cimg_forX(*
this,x) {
35035 *(ptr_r++) = (T)*(ptrs++);
35036 *(ptr_g++) = (T)*(ptrs++);
35037 *(ptr_b++) = (T)*(ptrs++);
35038 *(ptr_a++) = (T)*(ptrs++);
35043 jpeg_finish_decompress(&cinfo);
35044 jpeg_destroy_decompress(&cinfo);
35059 "load_magick(): Specified filename is (null).",
35062 #ifdef cimg_use_magick
35063 Magick::Image image(filename);
35064 const unsigned int W = image.size().width(), H = image.size().height();
35065 switch (image.type()) {
35066 case Magick::PaletteMatteType :
35067 case Magick::TrueColorMatteType :
35068 case Magick::ColorSeparationType : {
35070 T *ptr_r =
data(0,0,0,0), *ptr_g =
data(0,0,0,1), *ptr_b =
data(0,0,0,2), *ptr_a =
data(0,0,0,3);
35071 Magick::PixelPacket *pixels = image.getPixels(0,0,W,H);
35072 for (
unsigned long off = (
unsigned long)W*H; off; --off) {
35073 *(ptr_r++) = (T)(pixels->red);
35074 *(ptr_g++) = (T)(pixels->green);
35075 *(ptr_b++) = (T)(pixels->blue);
35076 *(ptr_a++) = (T)(pixels->opacity);
35080 case Magick::PaletteType :
35081 case Magick::TrueColorType : {
35083 T *ptr_r =
data(0,0,0,0), *ptr_g =
data(0,0,0,1), *ptr_b =
data(0,0,0,2);
35084 Magick::PixelPacket *pixels = image.getPixels(0,0,W,H);
35085 for (
unsigned long off = (
unsigned long)W*H; off; --off) {
35086 *(ptr_r++) = (T)(pixels->red);
35087 *(ptr_g++) = (T)(pixels->green);
35088 *(ptr_b++) = (T)(pixels->blue);
35092 case Magick::GrayscaleMatteType : {
35094 T *ptr_r =
data(0,0,0,0), *ptr_a =
data(0,0,0,1);
35095 Magick::PixelPacket *pixels = image.getPixels(0,0,W,H);
35096 for (
unsigned long off = (
unsigned long)W*H; off; --off) {
35097 *(ptr_r++) = (T)(pixels->red);
35098 *(ptr_a++) = (T)(pixels->opacity);
35104 T *ptr_r =
data(0,0,0,0);
35105 Magick::PixelPacket *pixels = image.getPixels(0,0,W,H);
35106 for (
unsigned long off = (
unsigned long)W*H; off; --off) {
35107 *(ptr_r++) = (T)(pixels->red);
35114 "load_magick(): Unable to load file '%s' unless libMagick++ is enabled.",
35131 return _load_png(0,filename);
35141 return _load_png(file,0);
35150 CImg<T>& _load_png(std::FILE *
const file,
const char *
const filename) {
35151 if (!file && !filename)
35153 "load_png(): Specified filename is (null).",
35156 #ifndef cimg_use_png
35159 "load_png(): Unable to load data from '(FILE*)' unless libpng is enabled.",
35165 const char *
volatile nfilename = filename;
35166 std::FILE *
volatile nfile = file?file:
cimg::fopen(nfilename,
"rb");
35168 unsigned char pngCheck[8] = { 0 };
35170 if (png_sig_cmp(pngCheck,0,8)) {
35172 throw CImgIOException(_cimg_instance
35173 "load_png(): Invalid PNG file '%s'.",
35175 nfilename?nfilename:
"(FILE*)");
35179 png_voidp user_error_ptr = 0;
35180 png_error_ptr user_error_fn = 0, user_warning_fn = 0;
35181 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,user_error_ptr,user_error_fn,user_warning_fn);
35184 throw CImgIOException(_cimg_instance
35185 "load_png(): Failed to initialize 'png_ptr' structure for file '%s'.",
35187 nfilename?nfilename:
"(FILE*)");
35189 png_infop info_ptr = png_create_info_struct(png_ptr);
35192 png_destroy_read_struct(&png_ptr,(png_infopp)0,(png_infopp)0);
35193 throw CImgIOException(_cimg_instance
35194 "load_png(): Failed to initialize 'info_ptr' structure for file '%s'.",
35196 nfilename?nfilename:
"(FILE*)");
35198 png_infop end_info = png_create_info_struct(png_ptr);
35201 png_destroy_read_struct(&png_ptr,&info_ptr,(png_infopp)0);
35202 throw CImgIOException(_cimg_instance
35203 "load_png(): Failed to initialize 'end_info' structure for file '%s'.",
35205 nfilename?nfilename:
"(FILE*)");
35209 if (setjmp(png_jmpbuf(png_ptr))) {
35211 png_destroy_read_struct(&png_ptr, &end_info, (png_infopp)0);
35212 throw CImgIOException(_cimg_instance
35213 "load_png(): Encountered unknown fatal error in libpng for file '%s'.",
35215 nfilename?nfilename:
"(FILE*)");
35217 png_init_io(png_ptr, nfile);
35218 png_set_sig_bytes(png_ptr, 8);
35221 png_read_info(png_ptr,info_ptr);
35223 int bit_depth, color_type, interlace_type;
35224 bool is_gray =
false;
35225 png_get_IHDR(png_ptr,info_ptr,&W,&H,&bit_depth,&color_type,&interlace_type,(
int*)0,(
int*)0);
35228 if (color_type==PNG_COLOR_TYPE_PALETTE) {
35229 png_set_palette_to_rgb(png_ptr);
35230 color_type = PNG_COLOR_TYPE_RGB;
35233 if (color_type==PNG_COLOR_TYPE_GRAY && bit_depth<8) {
35234 png_set_expand_gray_1_2_4_to_8(png_ptr);
35238 if (png_get_valid(png_ptr,info_ptr,PNG_INFO_tRNS)) {
35239 png_set_tRNS_to_alpha(png_ptr);
35240 color_type |= PNG_COLOR_MASK_ALPHA;
35242 if (color_type==PNG_COLOR_TYPE_GRAY || color_type==PNG_COLOR_TYPE_GRAY_ALPHA) {
35243 png_set_gray_to_rgb(png_ptr);
35244 color_type |= PNG_COLOR_MASK_COLOR;
35247 if (color_type==PNG_COLOR_TYPE_RGB)
35248 png_set_filler(png_ptr,0xffffU,PNG_FILLER_AFTER);
35250 png_read_update_info(png_ptr,info_ptr);
35251 if (bit_depth!=8 && bit_depth!=16) {
35253 png_destroy_read_struct(&png_ptr,&end_info,(png_infopp)0);
35254 throw CImgIOException(_cimg_instance
35255 "load_png(): Invalid bit depth %u in file '%s'.",
35257 bit_depth,nfilename?nfilename:
"(FILE*)");
35259 const int byte_depth = bit_depth>>3;
35262 png_bytep *
const imgData =
new png_bytep[H];
35263 for (
unsigned int row = 0;
row<H; ++
row) imgData[
row] =
new png_byte[byte_depth*4*W];
35264 png_read_image(png_ptr,imgData);
35265 png_read_end(png_ptr,end_info);
35268 if (color_type!=PNG_COLOR_TYPE_RGB && color_type!=PNG_COLOR_TYPE_RGB_ALPHA) {
35270 png_destroy_read_struct(&png_ptr,&end_info,(png_infopp)0);
35271 throw CImgIOException(_cimg_instance
35272 "load_png(): Invalid color coding type %u in file '%s'.",
35274 color_type,nfilename?nfilename:
"(FILE*)");
35276 const bool is_alpha = (color_type==PNG_COLOR_TYPE_RGBA);
35277 assign(W,H,1,(is_gray?1:3) + (is_alpha?1:0));
35279 *ptr_r =
data(0,0,0,0),
35280 *ptr_g = is_gray?0:
data(0,0,0,1),
35281 *ptr_b = is_gray?0:
data(0,0,0,2),
35282 *ptr_a = !is_alpha?0:
data(0,0,0,is_gray?1:3);
35283 switch (bit_depth) {
35285 cimg_forY(*
this,y) {
35286 const unsigned char *ptrs = (
unsigned char*)imgData[y];
35287 cimg_forX(*
this,x) {
35288 *(ptr_r++) = (T)*(ptrs++);
35289 if (ptr_g) *(ptr_g++) = (T)*(ptrs++);
else ++ptrs;
35290 if (ptr_b) *(ptr_b++) = (T)*(ptrs++);
else ++ptrs;
35291 if (ptr_a) *(ptr_a++) = (T)*(ptrs++);
else ++ptrs;
35296 cimg_forY(*
this,y) {
35297 const unsigned short *ptrs = (
unsigned short*)(imgData[y]);
35299 cimg_forX(*
this,x) {
35300 *(ptr_r++) = (T)*(ptrs++);
35301 if (ptr_g) *(ptr_g++) = (T)*(ptrs++);
else ++ptrs;
35302 if (ptr_b) *(ptr_b++) = (T)*(ptrs++);
else ++ptrs;
35303 if (ptr_a) *(ptr_a++) = (T)*(ptrs++);
else ++ptrs;
35308 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
35311 cimg_forY(*
this,n) delete[] imgData[n];
35313 if (!file) cimg::fclose(nfile);
35323 return _load_pnm(0,filename);
35333 return _load_pnm(file,0);
35341 CImg<T>& _load_pnm(std::FILE *
const file,
const char *
const filename) {
35342 if (!file && !filename)
35344 "load_pnm(): Specified filename is (null).",
35347 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"rb");
35348 unsigned int ppm_type, W, H, D = 1, colormax = 255;
35349 char item[1024] = { 0 };
35350 int err, rval, gval, bval;
35351 const long cimg_iobuffer = 12*1024*1024;
35352 while ((err=std::fscanf(nfile,
"%1023[^\n]",item))!=EOF && (*item==
'#' || !err)) std::fgetc(nfile);
35353 if (std::sscanf(item,
" P%u",&ppm_type)!=1) {
35355 throw CImgIOException(_cimg_instance
35356 "load_pnm(): PNM header not found in file '%s'.",
35358 filename?filename:
"(FILE*)");
35360 while ((err=std::fscanf(nfile,
" %1023[^\n]",item))!=EOF && (*item==
'#' || !err)) std::fgetc(nfile);
35361 if ((err=std::sscanf(item,
" %u %u %u %u",&W,&H,&D,&colormax))<2) {
35363 throw CImgIOException(_cimg_instance
35364 "load_pnm(): WIDTH and HEIGHT fields undefined in file '%s'.",
35366 filename?filename:
"(FILE*)");
35368 if (ppm_type!=1 && ppm_type!=4) {
35369 if (err==2 || (err==3 && (ppm_type==5 || ppm_type==7 || ppm_type==8 || ppm_type==9))) {
35370 while ((err=std::fscanf(nfile,
" %1023[^\n]",item))!=EOF && (*item==
'#' || !err)) std::fgetc(nfile);
35371 if (std::sscanf(item,
"%u",&colormax)!=1)
35373 "load_pnm(): COLORMAX field is undefined in file '%s'.",
35375 filename?filename:
"(FILE*)");
35376 }
else { colormax = D; D = 1; }
35380 switch (ppm_type) {
35384 cimg_foroff(*
this,off) {
if (std::fscanf(nfile,
"%d",&rval)>0) *(ptrd++) = (T)(rval?0:255);
else break; }
35389 cimg_foroff(*
this,off) {
if (std::fscanf(nfile,
"%d",&rval)>0) *(ptrd++) = (T)rval;
else break; }
35393 T *ptrd =
data(0,0,0,0), *ptr_g =
data(0,0,0,1), *ptr_b =
data(0,0,0,2);
35394 cimg_forXY(*
this,x,y) {
35395 if (std::fscanf(nfile,
"%d %d %d",&rval,&gval,&bval)==3) { *(ptrd++) = (T)rval; *(ptr_g++) = (T)gval; *(ptr_b++) = (T)bval; }
35402 T *ptrd =
data(0,0,0,0);
35403 unsigned int w = 0, h = 0, d = 0;
35404 for (
long to_read = (
long)((W/8 + (W%8?1:0))*H*D); to_read>0; ) {
35405 raw.assign(
cimg::min(to_read,cimg_iobuffer));
35407 to_read-=raw._width;
35408 const unsigned char *ptrs = raw._data;
35409 unsigned char mask = 0, val = 0;
35410 for (
unsigned long off = (
unsigned long)raw._width; off || mask; mask>>=1) {
35411 if (!mask) {
if (off--) val = *(ptrs++); mask = 128; }
35412 *(ptrd++) = (T)((val&mask)?0:255);
35413 if (++w==W) { w = 0; mask = 0;
if (++h==H) { h = 0;
if (++d==D)
break; }}
35417 case 5 :
case 7 : {
35418 if (colormax<256) {
35421 T *ptrd =
data(0,0,0,0);
35422 for (
long to_read = (
long)
size(); to_read>0; ) {
35423 raw.assign(
cimg::min(to_read,cimg_iobuffer));
35425 to_read-=raw._width;
35426 const unsigned char *ptrs = raw._data;
35427 for (
unsigned long off = (
unsigned long)raw._width; off; --off) *(ptrd++) = (T)*(ptrs++);
35432 T *ptrd =
data(0,0,0,0);
35433 for (
long to_read = (
long)
size(); to_read>0; ) {
35434 raw.assign(
cimg::min(to_read,cimg_iobuffer/2));
35437 to_read-=raw._width;
35438 const unsigned short *ptrs = raw._data;
35439 for (
unsigned long off = (
unsigned long)raw._width; off; --off) *(ptrd++) = (T)*(ptrs++);
35444 if (colormax<256) {
35448 *ptr_r =
data(0,0,0,0),
35449 *ptr_g =
data(0,0,0,1),
35450 *ptr_b =
data(0,0,0,2);
35451 for (
long to_read = (
long)
size(); to_read>0; ) {
35452 raw.assign(
cimg::min(to_read,cimg_iobuffer));
35454 to_read-=raw._width;
35455 const unsigned char *ptrs = raw._data;
35456 for (
unsigned long off = (
unsigned long)raw._width/3; off; --off) {
35457 *(ptr_r++) = (T)*(ptrs++);
35458 *(ptr_g++) = (T)*(ptrs++);
35459 *(ptr_b++) = (T)*(ptrs++);
35466 *ptr_r =
data(0,0,0,0),
35467 *ptr_g =
data(0,0,0,1),
35468 *ptr_b =
data(0,0,0,2);
35469 for (
long to_read = (
int)
size(); to_read>0; ) {
35470 raw.assign(
cimg::min(to_read,cimg_iobuffer/2));
35473 to_read-=raw._width;
35474 const unsigned short *ptrs = raw._data;
35475 for (
unsigned long off = (
unsigned long)raw._width/3; off; --off) {
35476 *(ptr_r++) = (T)*(ptrs++);
35477 *(ptr_g++) = (T)*(ptrs++);
35478 *(ptr_b++) = (T)*(ptrs++);
35486 T *ptrd =
data(0,0,0,0);
35487 for (
long to_read = (
long)
size(); to_read>0; ) {
35488 raw.assign(
cimg::min(to_read,cimg_iobuffer));
35490 to_read-=raw._width;
35491 const int *ptrs = raw._data;
35492 for (
unsigned long off = (
unsigned long)raw._width; off; --off) *(ptrd++) = (T)*(ptrs++);
35498 T *ptrd =
data(0,0,0,0);
35499 for (
long to_read = (
long)
size(); to_read>0; ) {
35500 raw.assign(
cimg::min(to_read,cimg_iobuffer));
35502 to_read-=raw._width;
35503 const float *ptrs = raw._data;
35504 for (
unsigned long off = (
unsigned long)raw._width; off; --off) *(ptrd++) = (T)*(ptrs++);
35510 throw CImgIOException(_cimg_instance
35511 "load_pnm(): PNM type 'P%d' found, but type is not supported.",
35513 filename?filename:
"(FILE*)",ppm_type);
35524 return _load_pfm(0,filename);
35534 return _load_pfm(file,0);
35542 CImg<T>& _load_pfm(std::FILE *
const file,
const char *
const filename) {
35543 if (!file && !filename)
35545 "load_pfm(): Specified filename is (null).",
35548 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"rb");
35549 char pfm_type, item[1024] = { 0 };
35550 int W = 0, H = 0, err = 0;
35552 while ((err=std::fscanf(nfile,
"%1023[^\n]",item))!=EOF && (*item==
'#' || !err)) std::fgetc(nfile);
35553 if (std::sscanf(item,
" P%c",&pfm_type)!=1) {
35555 throw CImgIOException(_cimg_instance
35556 "load_pfm(): PFM header not found in file '%s'.",
35558 filename?filename:
"(FILE*)");
35560 while ((err=std::fscanf(nfile,
" %1023[^\n]",item))!=EOF && (*item==
'#' || !err)) std::fgetc(nfile);
35561 if ((err=std::sscanf(item,
" %d %d",&W,&H))<2) {
35563 throw CImgIOException(_cimg_instance
35564 "load_pfm(): WIDTH and HEIGHT fields are undefined in file '%s'.",
35566 filename?filename:
"(FILE*)");
35569 while ((err=std::fscanf(nfile,
" %1023[^\n]",item))!=EOF && (*item==
'#' || !err)) std::fgetc(nfile);
35570 if (std::sscanf(item,
"%lf",&scale)!=1)
35572 "load_pfm(): SCALE field is undefined in file '%s'.",
35574 filename?filename:
"(FILE*)");
35577 const bool is_color = (pfm_type==
'F'), is_inverted = (scale>0)!=
cimg::endianness();
35580 CImg<floatT> buf(3*W);
35581 T *ptr_r =
data(0,0,0,0), *ptr_g =
data(0,0,0,1), *ptr_b =
data(0,0,0,2);
35582 cimg_forY(*
this,y) {
35585 const float *ptrs = buf._data;
35586 cimg_forX(*
this,x) {
35587 *(ptr_r++) = (T)*(ptrs++);
35588 *(ptr_g++) = (T)*(ptrs++);
35589 *(ptr_b++) = (T)*(ptrs++);
35594 CImg<floatT> buf(W);
35595 T *ptrd =
data(0,0,0,0);
35596 cimg_forY(*
this,y) {
35599 const float *ptrs = buf._data;
35600 cimg_forX(*
this,x) *(ptrd++) = (T)*(ptrs++);
35613 CImg<T>&
load_rgb(
const char *
const filename,
const unsigned int dimw,
const unsigned int dimh=1) {
35614 return _load_rgb(0,filename,dimw,dimh);
35623 CImg<T>&
load_rgb(std::FILE *
const file,
const unsigned int dimw,
const unsigned int dimh=1) {
35624 return _load_rgb(file,0,dimw,dimh);
35632 CImg<T>& _load_rgb(std::FILE *
const file,
const char *
const filename,
const unsigned int dimw,
const unsigned int dimh) {
35633 if (!file && !filename)
35635 "load_rgb(): Specified filename is (null).",
35638 if (!dimw || !dimh)
return assign();
35639 const long cimg_iobuffer = 12*1024*1024;
35640 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"rb");
35644 *ptr_r =
data(0,0,0,0),
35645 *ptr_g =
data(0,0,0,1),
35646 *ptr_b =
data(0,0,0,2);
35647 for (
long to_read = (
long)
size(); to_read>0; ) {
35648 raw.assign(
cimg::min(to_read,cimg_iobuffer));
35650 to_read-=raw._width;
35651 const unsigned char *ptrs = raw._data;
35652 for (
unsigned long off = raw._width/3UL; off; --off) {
35653 *(ptr_r++) = (T)*(ptrs++);
35654 *(ptr_g++) = (T)*(ptrs++);
35655 *(ptr_b++) = (T)*(ptrs++);
35668 CImg<T>&
load_rgba(
const char *
const filename,
const unsigned int dimw,
const unsigned int dimh=1) {
35669 return _load_rgba(0,filename,dimw,dimh);
35679 return _load_rgba(file,0,dimw,dimh);
35687 CImg<T>& _load_rgba(std::FILE *
const file,
const char *
const filename,
const unsigned int dimw,
const unsigned int dimh) {
35688 if (!file && !filename)
35690 "load_rgba(): Specified filename is (null).",
35693 if (!dimw || !dimh)
return assign();
35694 const long cimg_iobuffer = 12*1024*1024;
35695 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"rb");
35699 *ptr_r =
data(0,0,0,0),
35700 *ptr_g =
data(0,0,0,1),
35701 *ptr_b =
data(0,0,0,2),
35702 *ptr_a =
data(0,0,0,3);
35703 for (
long to_read = (
long)
size(); to_read>0; ) {
35704 raw.assign(
cimg::min(to_read,cimg_iobuffer));
35706 to_read-=raw._width;
35707 const unsigned char *ptrs = raw._data;
35708 for (
unsigned long off = raw._width/4UL; off; --off) {
35709 *(ptr_r++) = (T)*(ptrs++);
35710 *(ptr_g++) = (T)*(ptrs++);
35711 *(ptr_b++) = (T)*(ptrs++);
35712 *(ptr_a++) = (T)*(ptrs++);
35735 const unsigned int first_frame=0,
const unsigned int last_frame=~0U,
35736 const unsigned int step_frame=1) {
35739 "load_tiff(): Specified filename is (null).",
35743 nfirst_frame = first_frame<last_frame?first_frame:last_frame,
35744 nstep_frame = step_frame?step_frame:1;
35745 unsigned int nlast_frame = first_frame<last_frame?last_frame:first_frame;
35747 #ifndef cimg_use_tiff
35748 if (nfirst_frame || nlast_frame!=~0U || nstep_frame>1)
35750 "load_tiff(): Unable to read sub-images from file '%s' unless libtiff is enabled.",
35755 TIFF *tif = TIFFOpen(filename,
"r");
35757 unsigned int nb_images = 0;
35758 do ++nb_images;
while (TIFFReadDirectory(tif));
35759 if (nfirst_frame>=nb_images || (nlast_frame!=~0U && nlast_frame>=nb_images))
35761 "load_tiff(): File '%s' contains %u image(s) while specified frame range is [%u,%u] (step %u).",
35763 filename,nb_images,nfirst_frame,nlast_frame,nstep_frame);
35765 if (nfirst_frame>=nb_images)
return assign();
35766 if (nlast_frame>=nb_images) nlast_frame = nb_images-1;
35767 TIFFSetDirectory(tif,0);
35769 for (
unsigned int l = nfirst_frame; l<=nlast_frame; l+=nstep_frame) {
35770 frame._load_tiff(tif,l);
35771 if (l==nfirst_frame)
assign(frame._width,frame._height,1+(nlast_frame-nfirst_frame)/nstep_frame,frame._spectrum);
35772 if (frame._width>_width || frame._height>_height || frame._spectrum>_spectrum)
35774 draw_image(0,0,(l-nfirst_frame)/nstep_frame,frame);
35778 "load_tiff(): Failed to open file '%s'.",
35787 const unsigned int first_frame=0,
const unsigned int last_frame=~0U,
35788 const unsigned int step_frame=1) {
35793 #ifdef cimg_use_tiff
35794 template<
typename t>
35795 void _load_tiff_tiled_contig(TIFF *
const tif,
const uint16 samplesperpixel,
const uint32 nx,
const uint32 ny,
const uint32 tw,
const uint32 th) {
35796 t *
const buf = (t*)_TIFFmalloc(TIFFTileSize(tif));
35798 for (
unsigned int row = 0;
row<ny;
row+=th)
35799 for (
unsigned int col = 0; col<nx; col+=tw) {
35800 if (TIFFReadTile(tif,buf,col,
row,0,0)<0) {
35801 _TIFFfree(buf); TIFFClose(tif);
35803 "load_tiff(): Invalid tile in file '%s'.",
35805 TIFFFileName(tif));
35807 const t *ptr = buf;
35808 for (
unsigned int rr =
row; rr<
cimg::min((
unsigned int)(
row+th),(
unsigned int)ny); ++rr)
35809 for (
unsigned int cc = col; cc<
cimg::min((
unsigned int)(col+tw),(
unsigned int)nx); ++cc)
35810 for (
unsigned int vv = 0; vv<samplesperpixel; ++vv)
35811 (*
this)(cc,rr,vv) = (T)(ptr[(rr-
row)*th*samplesperpixel + (cc-col)*samplesperpixel + vv]);
35817 template<
typename t>
35818 void _load_tiff_tiled_separate(TIFF *
const tif,
const uint16 samplesperpixel,
const uint32 nx,
const uint32 ny,
const uint32 tw,
const uint32 th) {
35819 t *
const buf = (t*)_TIFFmalloc(TIFFTileSize(tif));
35821 for (
unsigned int vv = 0; vv<samplesperpixel; ++vv)
35822 for (
unsigned int row = 0;
row<ny;
row+=th)
35823 for (
unsigned int col = 0; col<nx; col+=tw) {
35824 if (TIFFReadTile(tif,buf,col,
row,0,vv)<0) {
35825 _TIFFfree(buf); TIFFClose(tif);
35826 throw CImgIOException(_cimg_instance
35827 "load_tiff(): Invalid tile in file '%s'.",
35829 TIFFFileName(tif));
35831 const t *ptr = buf;
35832 for (
unsigned int rr =
row; rr<
cimg::min((
unsigned int)(
row+th),(
unsigned int)ny); ++rr)
35833 for (
unsigned int cc = col; cc<
cimg::min((
unsigned int)(col+tw),(
unsigned int)nx); ++cc)
35834 (*
this)(cc,rr,vv) = (T)*(ptr++);
35840 template<
typename t>
35841 void _load_tiff_contig(TIFF *
const tif,
const uint16 samplesperpixel,
const uint32 nx,
const uint32 ny) {
35842 t *
const buf = (t*)_TIFFmalloc(TIFFStripSize(tif));
35844 uint32
row, rowsperstrip = (uint32)-1;
35845 TIFFGetField(tif,TIFFTAG_ROWSPERSTRIP,&rowsperstrip);
35846 for (row = 0; row<ny; row+= rowsperstrip) {
35847 uint32 nrow = (row+rowsperstrip>ny?ny-row:rowsperstrip);
35848 tstrip_t strip = TIFFComputeStrip(tif, row, 0);
35849 if ((TIFFReadEncodedStrip(tif,strip,buf,-1))<0) {
35850 _TIFFfree(buf); TIFFClose(tif);
35851 throw CImgIOException(_cimg_instance
35852 "load_tiff(): Invalid strip in file '%s'.",
35854 TIFFFileName(tif));
35856 const t *ptr = buf;
35857 for (
unsigned int rr = 0; rr<nrow; ++rr)
35858 for (
unsigned int cc = 0; cc<nx; ++cc)
35859 for (
unsigned int vv = 0; vv<samplesperpixel; ++vv) (*
this)(cc,row+rr,vv) = (T)*(ptr++);
35865 template<
typename t>
35866 void _load_tiff_separate(TIFF *
const tif,
const uint16 samplesperpixel,
const uint32 nx,
const uint32 ny) {
35867 t *buf = (t*)_TIFFmalloc(TIFFStripSize(tif));
35869 uint32
row, rowsperstrip = (uint32)-1;
35870 TIFFGetField(tif,TIFFTAG_ROWSPERSTRIP,&rowsperstrip);
35871 for (
unsigned int vv = 0; vv<samplesperpixel; ++vv)
35872 for (row = 0; row<ny; row+= rowsperstrip) {
35873 uint32 nrow = (row+rowsperstrip>ny?ny-row:rowsperstrip);
35874 tstrip_t strip = TIFFComputeStrip(tif, row, vv);
35875 if ((TIFFReadEncodedStrip(tif,strip,buf,-1))<0) {
35876 _TIFFfree(buf); TIFFClose(tif);
35877 throw CImgIOException(_cimg_instance
35878 "load_tiff(): Invalid strip in file '%s'.",
35880 TIFFFileName(tif));
35882 const t *ptr = buf;
35883 for (
unsigned int rr = 0;rr<nrow; ++rr)
35884 for (
unsigned int cc = 0; cc<nx; ++cc)
35885 (*
this)(cc,row+rr,vv) = (T)*(ptr++);
35891 CImg<T>& _load_tiff(TIFF *
const tif,
const unsigned int directory) {
35892 if (!TIFFSetDirectory(tif,directory))
return assign();
35893 uint16 samplesperpixel, bitspersample, photo;
35894 uint16 sampleformat = SAMPLEFORMAT_UINT;
35896 const char *
const filename = TIFFFileName(tif);
35897 TIFFGetField(tif,TIFFTAG_IMAGEWIDTH,&nx);
35898 TIFFGetField(tif,TIFFTAG_IMAGELENGTH,&ny);
35899 TIFFGetField(tif,TIFFTAG_SAMPLESPERPIXEL,&samplesperpixel);
35900 TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &sampleformat);
35901 TIFFGetFieldDefaulted(tif,TIFFTAG_BITSPERSAMPLE,&bitspersample);
35902 TIFFGetField(tif,TIFFTAG_PHOTOMETRIC,&photo);
35904 if (photo == 3) spectrum = 3;
35905 assign(nx,ny,1,spectrum);
35906 if ((photo < 3) && ( bitspersample!=8 || !(samplesperpixel==3 || samplesperpixel==4))) {
35908 TIFFGetField(tif,TIFFTAG_PLANARCONFIG,&config);
35909 if (TIFFIsTiled(tif)) {
35911 TIFFGetField(tif,TIFFTAG_TILEWIDTH,&tw);
35912 TIFFGetField(tif,TIFFTAG_TILELENGTH,&th);
35913 if (config==PLANARCONFIG_CONTIG)
switch (bitspersample) {
35915 if (sampleformat==SAMPLEFORMAT_UINT) _load_tiff_tiled_contig<unsigned char>(tif,samplesperpixel,nx,ny,tw,th);
35916 else _load_tiff_tiled_contig<signed char>(tif,samplesperpixel,nx,ny,tw,th);
35919 if (sampleformat==SAMPLEFORMAT_UINT) _load_tiff_tiled_contig<unsigned short>(tif,samplesperpixel,nx,ny,tw,th);
35920 else _load_tiff_tiled_contig<short>(tif,samplesperpixel,nx,ny,tw,th);
35923 if (sampleformat==SAMPLEFORMAT_UINT) _load_tiff_tiled_contig<unsigned int>(tif,samplesperpixel,nx,ny,tw,th);
35924 else if (sampleformat==SAMPLEFORMAT_INT) _load_tiff_tiled_contig<int>(tif,samplesperpixel,nx,ny,tw,th);
35925 else _load_tiff_tiled_contig<float>(tif,samplesperpixel,nx,ny,tw,th);
35927 }
else switch (bitspersample) {
35929 if (sampleformat==SAMPLEFORMAT_UINT) _load_tiff_tiled_separate<unsigned char>(tif,samplesperpixel,nx,ny,tw,th);
35930 else _load_tiff_tiled_separate<signed char>(tif,samplesperpixel,nx,ny,tw,th);
35933 if (sampleformat==SAMPLEFORMAT_UINT) _load_tiff_tiled_separate<unsigned short>(tif,samplesperpixel,nx,ny,tw,th);
35934 else _load_tiff_tiled_separate<short>(tif,samplesperpixel,nx,ny,tw,th);
35937 if (sampleformat==SAMPLEFORMAT_UINT) _load_tiff_tiled_separate<unsigned int>(tif,samplesperpixel,nx,ny,tw,th);
35938 else if (sampleformat==SAMPLEFORMAT_INT) _load_tiff_tiled_separate<int>(tif,samplesperpixel,nx,ny,tw,th);
35939 else _load_tiff_tiled_separate<float>(tif,samplesperpixel,nx,ny,tw,th);
35943 if (config==PLANARCONFIG_CONTIG)
switch (bitspersample) {
35945 if (sampleformat==SAMPLEFORMAT_UINT) _load_tiff_contig<unsigned char>(tif,samplesperpixel,nx,ny);
35946 else _load_tiff_contig<signed char>(tif,samplesperpixel,nx,ny);
35949 if (sampleformat==SAMPLEFORMAT_UINT) _load_tiff_contig<unsigned short>(tif,samplesperpixel,nx,ny);
35950 else _load_tiff_contig<short>(tif,samplesperpixel,nx,ny);
35953 if (sampleformat==SAMPLEFORMAT_UINT) _load_tiff_contig<unsigned int>(tif,samplesperpixel,nx,ny);
35954 else if (sampleformat==SAMPLEFORMAT_INT) _load_tiff_contig<int>(tif,samplesperpixel,nx,ny);
35955 else _load_tiff_contig<float>(tif,samplesperpixel,nx,ny);
35957 }
else switch (bitspersample){
35959 if (sampleformat==SAMPLEFORMAT_UINT) _load_tiff_separate<unsigned char>(tif,samplesperpixel,nx,ny);
35960 else _load_tiff_separate<signed char>(tif,samplesperpixel,nx,ny);
35963 if (sampleformat==SAMPLEFORMAT_UINT) _load_tiff_separate<unsigned short>(tif,samplesperpixel,nx,ny);
35964 else _load_tiff_separate<short>(tif,samplesperpixel,nx,ny);
35967 if (sampleformat==SAMPLEFORMAT_UINT) _load_tiff_separate<unsigned int>(tif,samplesperpixel,nx,ny);
35968 else if (sampleformat==SAMPLEFORMAT_INT) _load_tiff_separate<int>(tif,samplesperpixel,nx,ny);
35969 else _load_tiff_separate<float>(tif,samplesperpixel,nx,ny);
35974 uint32 *
const raster = (uint32*)_TIFFmalloc(nx*ny*
sizeof(uint32));
35976 _TIFFfree(raster); TIFFClose(tif);
35977 throw CImgException(_cimg_instance
35978 "load_tiff(): Failed to allocate memory (%s) for file '%s'.",
35980 cimg::strbuffersize(nx*ny*
sizeof(uint32)),filename);
35982 TIFFReadRGBAImage(tif,nx,ny,raster,0);
35983 switch (spectrum) {
35985 cimg_forXY(*
this,x,y) (*this)(x,y) = (T)(float)((raster[nx*(ny-1-y)+x] + 128)/257);
35988 cimg_forXY(*
this,x,y) {
35989 (*this)(x,y,0) = (T)(float)TIFFGetR(raster[nx*(ny-1-y)+x]);
35990 (*this)(x,y,1) = (T)(float)TIFFGetG(raster[nx*(ny-1-y)+x]);
35991 (*this)(x,y,2) = (T)(float)TIFFGetB(raster[nx*(ny-1-y)+x]);
35995 cimg_forXY(*
this,x,y) {
35996 (*this)(x,y,0) = (T)(float)TIFFGetR(raster[nx*(ny-1-y)+x]);
35997 (*this)(x,y,1) = (T)(float)TIFFGetG(raster[nx*(ny-1-y)+x]);
35998 (*this)(x,y,2) = (T)(float)TIFFGetB(raster[nx*(ny-1-y)+x]);
35999 (*this)(x,y,3) = (T)(float)TIFFGetA(raster[nx*(ny-1-y)+x]);
36017 "load_minc2(): Specified filename is (null).",
36019 #ifndef cimg_use_minc2
36022 minc::minc_1_reader rdr;
36023 rdr.open(filename);
36024 assign(rdr.ndim(1)?rdr.ndim(1):1,
36025 rdr.ndim(2)?rdr.ndim(2):1,
36026 rdr.ndim(3)?rdr.ndim(3):1,
36027 rdr.ndim(4)?rdr.ndim(4):1);
36028 if(
typeid(T)==
typeid(
unsigned char))
36029 rdr.setup_read_byte();
36030 else if(
typeid(T)==
typeid(
int))
36031 rdr.setup_read_int();
36032 else if(
typeid(T)==
typeid(
double))
36033 rdr.setup_read_double();
36035 rdr.setup_read_float();
36036 minc::load_standard_volume(rdr, this->_data);
36052 return _load_analyze(0,filename,voxel_size);
36062 return _load_analyze(file,0,voxel_size);
36070 CImg<T>& _load_analyze(std::FILE *
const file,
const char *
const filename,
float *
const voxel_size=0) {
36071 if (!file && !filename)
36073 "load_analyze(): Specified filename is (null).",
36076 std::FILE *nfile_header = 0, *nfile = 0;
36078 char body[1024] = { 0 };
36082 std::sprintf(body + std::strlen(body),
".img");
36086 std::sprintf(body + std::strlen(body),
".hdr");
36088 }
else nfile_header = nfile =
cimg::fopen(filename,
"rb");
36089 }
else nfile_header = nfile = file;
36090 if (!nfile || !nfile_header)
36091 throw CImgIOException(_cimg_instance
36092 "load_analyze(): Invalid Analyze7.5 or NIFTI header in file '%s'.",
36094 filename?filename:
"(FILE*)");
36097 bool endian =
false;
36098 unsigned int header_size;
36101 throw CImgIOException(_cimg_instance
36102 "load_analyze(): Invalid zero-sized header in file '%s'.",
36104 filename?filename:
"(FILE*)");
36107 unsigned char *
const header =
new unsigned char[header_size];
36108 cimg::fread(header+4,header_size-4,nfile_header);
36109 if (!file && nfile_header!=nfile)
cimg::fclose(nfile_header);
36117 unsigned short *dim = (
unsigned short*)(header+40), dimx = 1, dimy = 1, dimz = 1, dimv = 1;
36120 "load_analyze(): File '%s' defines an image with zero dimensions.",
36122 filename?filename:
"(FILE*)");
36126 "load_analyze(): File '%s' defines an image with %u dimensions, reading only the 4 first.",
36128 filename?filename:
"(FILE*)",dim[0]);
36130 if (dim[0]>=1) dimx = dim[1];
36131 if (dim[0]>=2) dimy = dim[2];
36132 if (dim[0]>=3) dimz = dim[3];
36133 if (dim[0]>=4) dimv = dim[4];
36134 float scalefactor = *(
float*)(header+112);
if (scalefactor==0) scalefactor=1;
36135 const unsigned short datatype = *(
short*)(header+70);
36137 const float *vsize = (
float*)(header+76);
36138 voxel_size[0] = vsize[1]; voxel_size[1] = vsize[2]; voxel_size[2] = vsize[3];
36143 assign(dimx,dimy,dimz,dimv);
36144 switch (datatype) {
36146 unsigned char *
const buffer =
new unsigned char[dimx*dimy*dimz*dimv];
36148 cimg_foroff(*
this,off) _data[off] = (T)(buffer[off]*scalefactor);
36152 short *
const buffer =
new short[dimx*dimy*dimz*dimv];
36155 cimg_foroff(*
this,off) _data[off] = (T)(buffer[off]*scalefactor);
36159 int *
const buffer =
new int[dimx*dimy*dimz*dimv];
36162 cimg_foroff(*
this,off) _data[off] = (T)(buffer[off]*scalefactor);
36166 float *
const buffer =
new float[dimx*dimy*dimz*dimv];
36169 cimg_foroff(*
this,off) _data[off] = (T)(buffer[off]*scalefactor);
36173 double *
const buffer =
new double[dimx*dimy*dimz*dimv];
36176 cimg_foroff(*
this,off) _data[off] = (T)(buffer[off]*scalefactor);
36180 if (!file) cimg::fclose(nfile);
36181 throw CImgIOException(_cimg_instance
36184 datatype,filename?filename:"(FILE*)");
36186 if (!file) cimg::fclose(nfile);
36196 CImg<T>&
load_cimg(const
char *const filename, const
char axis='z', const
float align=0) {
36199 if (list._width==1)
return list[0].
move_to(*
this);
36212 if (list._width==1)
return list[0].
move_to(*
this);
36238 const unsigned int n0,
const unsigned int n1,
36239 const unsigned int x0,
const unsigned int y0,
const unsigned int z0,
const unsigned int c0,
36240 const unsigned int x1,
const unsigned int y1,
const unsigned int z1,
const unsigned int c1,
36241 const char axis=
'z',
const float align=0) {
36243 list.
load_cimg(filename,n0,n1,x0,y0,z0,c0,x1,y1,z1,c1);
36244 if (list._width==1)
return list[0].
move_to(*
this);
36250 const unsigned int n0,
const unsigned int n1,
36251 const unsigned int x0,
const unsigned int y0,
const unsigned int z0,
const unsigned int c0,
36252 const unsigned int x1,
const unsigned int y1,
const unsigned int z1,
const unsigned int c1,
36253 const char axis=
'z',
const float align=0) {
36254 return CImg<T>().
load_cimg(filename,n0,n1,x0,y0,z0,c0,x1,y1,z1,c1,axis,align);
36259 const unsigned int n0,
const unsigned int n1,
36260 const unsigned int x0,
const unsigned int y0,
const unsigned int z0,
const unsigned int c0,
36261 const unsigned int x1,
const unsigned int y1,
const unsigned int z1,
const unsigned int c1,
36262 const char axis=
'z',
const float align=0) {
36264 list.
load_cimg(file,n0,n1,x0,y0,z0,c0,x1,y1,z1,c1);
36265 if (list._width==1)
return list[0].
move_to(*
this);
36271 const unsigned int n0,
const unsigned int n1,
36272 const unsigned int x0,
const unsigned int y0,
const unsigned int z0,
const unsigned int c0,
36273 const unsigned int x1,
const unsigned int y1,
const unsigned int z1,
const unsigned int c1,
36274 const char axis=
'z',
const float align=0) {
36275 return CImg<T>().
load_cimg(file,n0,n1,x0,y0,z0,c0,x1,y1,z1,c1,axis,align);
36284 return _load_inr(0,filename,voxel_size);
36294 return _load_inr(file,0,voxel_size);
36302 static void _load_inr_header(std::FILE *file,
int out[8],
float *
const voxel_size) {
36303 char item[1024] = { 0 }, tmp1[64] = { 0 }, tmp2[64] = { 0 };
36304 out[0] = std::fscanf(file,
"%63s",item);
36305 out[0] = out[1] = out[2] = out[3] = out[5] = 1; out[4] = out[6] = out[7] = -1;
36307 throw CImgIOException(
"CImg<%s>::load_inr(): INRIMAGE-4 header not found.",
36310 while (std::fscanf(file,
" %63[^\n]%*c",item)!=EOF && std::strncmp(item,
"##}",3)) {
36311 std::sscanf(item,
" XDIM%*[^0-9]%d",out);
36312 std::sscanf(item,
" YDIM%*[^0-9]%d",out+1);
36313 std::sscanf(item,
" ZDIM%*[^0-9]%d",out+2);
36314 std::sscanf(item,
" VDIM%*[^0-9]%d",out+3);
36315 std::sscanf(item,
" PIXSIZE%*[^0-9]%d",out+6);
36317 std::sscanf(item,
" VX%*[^0-9.+-]%f",voxel_size);
36318 std::sscanf(item,
" VY%*[^0-9.+-]%f",voxel_size+1);
36319 std::sscanf(item,
" VZ%*[^0-9.+-]%f",voxel_size+2);
36321 if (std::sscanf(item,
" CPU%*[ =]%s",tmp1)) out[7]=
cimg::strncasecmp(tmp1,
"sun",3)?0:1;
36322 switch (std::sscanf(item,
" TYPE%*[ =]%s %s",tmp1,tmp2)) {
36324 case 2 : out[5] =
cimg::strncasecmp(tmp1,
"unsigned",8)?1:0; std::strncpy(tmp1,tmp2,
sizeof(tmp1)-1);
36329 if (out[4]>=0)
break;
36331 throw CImgIOException(
"CImg<%s>::load_inr(): Invalid pixel type '%s' defined in header.",
36336 if(out[0]<0 || out[1]<0 || out[2]<0 || out[3]<0)
36337 throw CImgIOException(
"CImg<%s>::load_inr(): Invalid dimensions (%d,%d,%d,%d) defined in header.",
36339 out[0],out[1],out[2],out[3]);
36340 if(out[4]<0 || out[5]<0)
36341 throw CImgIOException(
"CImg<%s>::load_inr(): Incomplete pixel type defined in header.",
36344 throw CImgIOException(
"CImg<%s>::load_inr(): Incomplete PIXSIZE field defined in header.",
36347 throw CImgIOException(
"CImg<%s>::load_inr(): Big/Little Endian coding type undefined in header.",
36351 CImg<T>& _load_inr(std::FILE *
const file,
const char *
const filename,
float *
const voxel_size) {
36352 #define _cimg_load_inr_case(Tf,sign,pixsize,Ts) \
36353 if (!loaded && fopt[6]==pixsize && fopt[4]==Tf && fopt[5]==sign) { \
36354 Ts *xval, *const val = new Ts[fopt[0]*fopt[3]]; \
36355 cimg_forYZ(*this,y,z) { \
36356 cimg::fread(val,fopt[0]*fopt[3],nfile); \
36357 if (fopt[7]!=endian) cimg::invert_endianness(val,fopt[0]*fopt[3]); \
36358 xval = val; cimg_forX(*this,x) cimg_forC(*this,c) (*this)(x,y,z,c) = (T)*(xval++); \
36364 if (!file && !filename)
36365 throw CImgArgumentException(_cimg_instance
36366 "load_inr(): Specified filename is (null).",
36369 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"rb");
36371 bool loaded =
false;
36372 if (voxel_size) voxel_size[0] = voxel_size[1] = voxel_size[2] = 1;
36373 _load_inr_header(nfile,fopt,voxel_size);
36374 assign(fopt[0],fopt[1],fopt[2],fopt[3]);
36375 _cimg_load_inr_case(0,0,8,
unsigned char);
36376 _cimg_load_inr_case(0,1,8,
char);
36377 _cimg_load_inr_case(0,0,16,
unsigned short);
36378 _cimg_load_inr_case(0,1,16,
short);
36379 _cimg_load_inr_case(0,0,32,
unsigned int);
36380 _cimg_load_inr_case(0,1,32,
int);
36381 _cimg_load_inr_case(1,0,32,
float);
36382 _cimg_load_inr_case(1,1,32,
float);
36383 _cimg_load_inr_case(1,0,64,
double);
36384 _cimg_load_inr_case(1,1,64,
double);
36387 throw CImgIOException(_cimg_instance
36388 "load_inr(): Unknown pixel type defined in file '%s'.",
36390 filename?filename:
"(FILE*)");
36403 "load_exr(): Specified filename is (null).",
36406 #ifndef cimg_use_openexr
36409 Imf::RgbaInputFile file(filename);
36410 Imath::Box2i dw = file.dataWindow();
36412 inwidth = dw.max.x - dw.min.x + 1,
36413 inheight = dw.max.y - dw.min.y + 1;
36414 Imf::Array2D<Imf::Rgba> pixels;
36415 pixels.resizeErase(inheight,inwidth);
36416 file.setFrameBuffer(&pixels[0][0] - dw.min.x - dw.min.y*inwidth, 1, inwidth);
36417 file.readPixels(dw.min.y, dw.max.y);
36418 assign(inwidth,inheight,1,4);
36419 T *ptr_r =
data(0,0,0,0), *ptr_g =
data(0,0,0,1), *ptr_b =
data(0,0,0,2), *ptr_a =
data(0,0,0,3);
36420 cimg_forXY(*
this,x,y) {
36421 *(ptr_r++) = (T)pixels[y][x].r;
36422 *(ptr_g++) = (T)pixels[y][x].g;
36423 *(ptr_b++) = (T)pixels[y][x].b;
36424 *(ptr_a++) = (T)pixels[y][x].a;
36440 return _load_pandore(0,filename);
36450 return _load_pandore(file,0);
36458 CImg<T>& _load_pandore(std::FILE *
const file,
const char *
const filename) {
36459 #define __cimg_load_pandore_case(nbdim,nwidth,nheight,ndepth,ndim,stype) \
36460 cimg::fread(dims,nbdim,nfile); \
36461 if (endian) cimg::invert_endianness(dims,nbdim); \
36462 assign(nwidth,nheight,ndepth,ndim); \
36463 const unsigned int siz = size(); \
36464 stype *buffer = new stype[siz]; \
36465 cimg::fread(buffer,siz,nfile); \
36466 if (endian) cimg::invert_endianness(buffer,siz); \
36468 cimg_foroff(*this,off) *(ptrd++) = (T)*(buffer++); \
36472 #define _cimg_load_pandore_case(nbdim,nwidth,nheight,ndepth,dim,stype1,stype2,stype3,ltype) { \
36473 if (sizeof(stype1)==ltype) { __cimg_load_pandore_case(nbdim,nwidth,nheight,ndepth,dim,stype1); } \
36474 else if (sizeof(stype2)==ltype) { __cimg_load_pandore_case(nbdim,nwidth,nheight,ndepth,dim,stype2); } \
36475 else if (sizeof(stype3)==ltype) { __cimg_load_pandore_case(nbdim,nwidth,nheight,ndepth,dim,stype3); } \
36476 else throw CImgIOException(_cimg_instance \
36477 "load_pandore(): Unknown pixel datatype in file '%s'.", \
36479 filename?filename:"(FILE*)"); }
36481 if (!file && !filename)
36483 "load_pandore(): Specified filename is (null).",
36486 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"rb");
36487 char header[32] = { 0 };
36491 throw CImgIOException(_cimg_instance
36492 "load_pandore(): PANDORE header not found in file '%s'.",
36494 filename?filename:
"(FILE*)");
36496 unsigned int imageid, dims[8] = { 0 };
36498 const bool endian = (imageid>255);
36503 case 2: _cimg_load_pandore_case(2,dims[1],1,1,1,
unsigned char,
unsigned char,
unsigned char,1);
break;
36504 case 3: _cimg_load_pandore_case(2,dims[1],1,1,1,
long,
int,
short,4);
break;
36505 case 4: _cimg_load_pandore_case(2,dims[1],1,1,1,
double,
float,
float,4);
break;
36506 case 5: _cimg_load_pandore_case(3,dims[2],dims[1],1,1,
unsigned char,
unsigned char,
unsigned char,1);
break;
36507 case 6: _cimg_load_pandore_case(3,dims[2],dims[1],1,1,
long,
int,
short,4);
break;
36508 case 7: _cimg_load_pandore_case(3,dims[2],dims[1],1,1,
double,
float,
float,4);
break;
36509 case 8: _cimg_load_pandore_case(4,dims[3],dims[2],dims[1],1,
unsigned char,
unsigned char,
unsigned char,1);
break;
36510 case 9: _cimg_load_pandore_case(4,dims[3],dims[2],dims[1],1,
long,
int,
short,4);
break;
36511 case 10: _cimg_load_pandore_case(4,dims[3],dims[2],dims[1],1,
double,
float,
float,4);
break;
36516 const unsigned siz =
size();
36518 unsigned char *buffer =
new unsigned char[siz];
36521 cimg_foroff(*
this,off) *(ptrd++) = (T)*(buffer++);
36525 if (dims[2]<65536) {
36526 unsigned short *buffer =
new unsigned short[siz];
36530 cimg_foroff(*
this,off) *(ptrd++) = (T)*(buffer++);
36534 unsigned int *buffer =
new unsigned int[siz];
36538 cimg_foroff(*
this,off) *(ptrd++) = (T)*(buffer++);
36548 assign(dims[2],dims[1],1,1);
36549 const unsigned int siz =
size();
36551 unsigned char *buffer =
new unsigned char[siz];
36554 cimg_foroff(*
this,off) *(ptrd++) = (T)*(buffer++);
36558 if (dims[3]<65536) {
36559 unsigned short *buffer =
new unsigned short[siz];
36563 cimg_foroff(*
this,off) *(ptrd++) = (T)*(buffer++);
36567 unsigned long *buffer =
new unsigned long[siz];
36571 cimg_foroff(*
this,off) *(ptrd++) = (T)*(buffer++);
36581 assign(dims[3],dims[2],dims[1],1);
36582 const unsigned int siz =
size();
36584 unsigned char *buffer =
new unsigned char[siz];
36587 cimg_foroff(*
this,off) *(ptrd++) = (T)*(buffer++);
36591 if (dims[4]<65536) {
36592 unsigned short *buffer =
new unsigned short[siz];
36596 cimg_foroff(*
this,off) *(ptrd++) = (T)*(buffer++);
36600 unsigned int *buffer =
new unsigned int[siz];
36604 cimg_foroff(*
this,off) *(ptrd++) = (T)*(buffer++);
36611 case 16: _cimg_load_pandore_case(4,dims[2],dims[1],1,3,
unsigned char,
unsigned char,
unsigned char,1);
break;
36612 case 17: _cimg_load_pandore_case(4,dims[2],dims[1],1,3,
long,
int,
short,4);
break;
36613 case 18: _cimg_load_pandore_case(4,dims[2],dims[1],1,3,
double,
float,
float,4);
break;
36614 case 19: _cimg_load_pandore_case(5,dims[3],dims[2],dims[1],3,
unsigned char,
unsigned char,
unsigned char,1);
break;
36615 case 20: _cimg_load_pandore_case(5,dims[3],dims[2],dims[1],3,
long,
int,
short,4);
break;
36616 case 21: _cimg_load_pandore_case(5,dims[3],dims[2],dims[1],3,
double,
float,
float,4);
break;
36617 case 22: _cimg_load_pandore_case(2,dims[1],1,1,dims[0],
unsigned char,
unsigned char,
unsigned char,1);
break;
36618 case 23: _cimg_load_pandore_case(2,dims[1],1,1,dims[0],
long,
int,
short,4);
36619 case 24: _cimg_load_pandore_case(2,dims[1],1,1,dims[0],
unsigned long,
unsigned int,
unsigned short,4);
break;
36620 case 25: _cimg_load_pandore_case(2,dims[1],1,1,dims[0],
double,
float,
float,4);
break;
36621 case 26: _cimg_load_pandore_case(3,dims[2],dims[1],1,dims[0],
unsigned char,
unsigned char,
unsigned char,1);
break;
36622 case 27: _cimg_load_pandore_case(3,dims[2],dims[1],1,dims[0],
long,
int,
short,4);
break;
36623 case 28: _cimg_load_pandore_case(3,dims[2],dims[1],1,dims[0],
unsigned long,
unsigned int,
unsigned short,4);
break;
36624 case 29: _cimg_load_pandore_case(3,dims[2],dims[1],1,dims[0],
double,
float,
float,4);
break;
36625 case 30: _cimg_load_pandore_case(4,dims[3],dims[2],dims[1],dims[0],
unsigned char,
unsigned char,
unsigned char,1);
break;
36626 case 31: _cimg_load_pandore_case(4,dims[3],dims[2],dims[1],dims[0],
long,
int,
short,4);
break;
36627 case 32: _cimg_load_pandore_case(4,dims[3],dims[2],dims[1],dims[0],
unsigned long,
unsigned int,
unsigned short,4);
break;
36628 case 33: _cimg_load_pandore_case(4,dims[3],dims[2],dims[1],dims[0],
double,
float,
float,4);
break;
36630 int ptbuf[4] = { 0 };
36633 assign(1); (*this)(0) = (T)ptbuf[0];
36636 int ptbuf[4] = { 0 };
36639 assign(2); (*this)(0) = (T)ptbuf[1]; (*this)(1) = (T)ptbuf[0];
36642 int ptbuf[4] = { 0 };
36645 assign(3); (*this)(0) = (T)ptbuf[2]; (*this)(1) = (T)ptbuf[1]; (*this)(2) = (T)ptbuf[0];
36648 if (!file) cimg::fclose(nfile);
36649 throw CImgIOException(_cimg_instance
36652 imageid,filename?filename:"(FILE*)");
36654 if (!file) cimg::fclose(nfile);
36667 if (list._width==1)
return list[0].
move_to(*
this);
36687 const unsigned int size_x=0,
const unsigned int size_y=1,
36688 const unsigned int size_z=1,
const unsigned int size_c=1,
36690 return _load_raw(0,filename,size_x,size_y,size_z,size_c,is_multiplexed,
invert_endianness);
36695 const unsigned int size_x=0,
const unsigned int size_y=1,
36696 const unsigned int size_z=1,
const unsigned int size_c=1,
36703 const unsigned int size_x=0,
const unsigned int size_y=1,
36704 const unsigned int size_z=1,
const unsigned int size_c=1,
36706 return _load_raw(file,0,size_x,size_y,size_z,size_c,is_multiplexed,
invert_endianness);
36711 const unsigned int size_x=0,
const unsigned int size_y=1,
36712 const unsigned int size_z=1,
const unsigned int size_c=1,
36717 CImg<T>& _load_raw(std::FILE *
const file,
const char *
const filename,
36718 const unsigned int size_x,
const unsigned int size_y,
36719 const unsigned int size_z,
const unsigned int size_c,
36721 if (!file && !filename)
36723 "load_raw(): Specified filename is (null).",
36725 unsigned int siz = size_x*size_y*size_z*size_c, _size_x = size_x, _size_y = size_y, _size_z = size_z, _size_c = size_c;
36726 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"rb");
36728 const long fpos = std::ftell(nfile);
36730 "load_raw(): Cannot determine size of input file '%s'.",
36731 cimg_instance,filename?filename:
"(FILE*)");
36732 std::fseek(nfile,0,SEEK_END);
36733 siz = _size_y = (
unsigned int)std::ftell(nfile)/
sizeof(T);
36734 _size_x = _size_z = _size_c = 1;
36735 std::fseek(nfile,fpos,SEEK_SET);
36737 assign(_size_x,_size_y,_size_z,_size_c,0);
36738 if (!is_multiplexed || size_c==1) {
36742 CImg<T> buf(1,1,1,_size_c);
36743 cimg_forXYZ(*
this,x,y,z) {
36764 CImg<T>&
load_ffmpeg(
const char *
const filename,
const unsigned int first_frame=0,
const unsigned int last_frame=~0U,
36765 const unsigned int step_frame=1,
const bool pixel_format=
true,
const bool resume=
false,
36766 const char axis=
'z',
const float align=0) {
36767 return get_load_ffmpeg(filename,first_frame,last_frame,step_frame,pixel_format,resume,axis,align).move_to(*
this);
36772 const unsigned int step_frame=1,
const bool pixel_format=
true,
const bool resume=
false,
36773 const char axis=
'z',
const float align=0) {
36774 return CImgList<T>().
load_ffmpeg(filename,first_frame,last_frame,step_frame,pixel_format,resume).get_append(axis,align);
36789 const unsigned int size_x,
const unsigned int size_y=1,
36790 const unsigned int first_frame=0,
const unsigned int last_frame=~0U,
36791 const unsigned int step_frame=1,
const bool yuv2rgb=
true,
const char axis=
'z') {
36792 return get_load_yuv(filename,size_x,size_y,first_frame,last_frame,step_frame,yuv2rgb,axis).move_to(*
this);
36797 const unsigned int size_x,
const unsigned int size_y=1,
36798 const unsigned int first_frame=0,
const unsigned int last_frame=~0U,
36799 const unsigned int step_frame=1,
const bool yuv2rgb=
true,
const char axis=
'z') {
36800 return CImgList<T>().
load_yuv(filename,size_x,size_y,first_frame,last_frame,step_frame,yuv2rgb).get_append(axis);
36805 const unsigned int size_x,
const unsigned int size_y=1,
36806 const unsigned int first_frame=0,
const unsigned int last_frame=~0U,
36807 const unsigned int step_frame=1,
const bool yuv2rgb=
true,
const char axis=
'z') {
36808 return get_load_yuv(file,size_x,size_y,first_frame,last_frame,step_frame,yuv2rgb,axis).move_to(*
this);
36813 const unsigned int size_x,
const unsigned int size_y=1,
36814 const unsigned int first_frame=0,
const unsigned int last_frame=~0U,
36815 const unsigned int step_frame=1,
const bool yuv2rgb=
true,
const char axis=
'z') {
36816 return CImgList<T>().
load_yuv(file,size_x,size_y,first_frame,last_frame,step_frame,yuv2rgb).get_append(axis);
36825 template<
typename tf,
typename tc>
36827 return _load_off(primitives,colors,0,filename);
36831 template<
typename tf,
typename tc>
36837 template<
typename tf,
typename tc>
36839 return _load_off(primitives,colors,file,0);
36843 template<
typename tf,
typename tc>
36848 template<
typename tf,
typename tc>
36850 std::FILE *
const file,
const char *
const filename) {
36851 if (!file && !filename)
36853 "load_off(): Specified filename is (null).",
36856 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"r");
36857 unsigned int nb_points = 0, nb_primitives = 0, nb_read = 0;
36858 char line[256] = { 0 };
36862 do { err = std::fscanf(nfile,
"%255[^\n] ",line); }
while (!err || (err==1 && *line==
'#'));
36865 throw CImgIOException(_cimg_instance
36866 "load_off(): OFF header not found in file '%s'.",
36868 filename?filename:
"(FILE*)");
36870 do { err = std::fscanf(nfile,
"%255[^\n] ",line); }
while (!err || (err==1 && *line==
'#'));
36871 if ((err = std::sscanf(line,
"%u%u%*[^\n] ",&nb_points,&nb_primitives))!=2) {
36873 throw CImgIOException(_cimg_instance
36874 "load_off(): Invalid number of vertices or primitives specified in file '%s'.",
36876 filename?filename:
"(FILE*)");
36881 float X = 0, Y = 0, Z = 0;
36882 cimg_forX(*
this,l) {
36883 do { err = std::fscanf(nfile,
"%255[^\n] ",line); }
while (!err || (err==1 && *line==
'#'));
36884 if ((err = std::sscanf(line,
"%f%f%f%*[^\n] ",&X,&Y,&Z))!=3) {
36886 throw CImgIOException(_cimg_instance
36887 "load_off(): Failed to read vertex %u/%u in file '%s'.",
36889 l+1,nb_points,filename?filename:
"(FILE*)");
36891 (*this)(l,0) = (T)X; (*this)(l,1) = (T)Y; (*this)(l,2) = (T)Z;
36897 bool stopflag = false;
36898 while (!stopflag) {
36899 float c0 = 0.7f, c1 = 0.7f, c2 = 0.7f;
36900 unsigned int prim = 0, i0 = 0, i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0;
36902 if ((err = std::fscanf(nfile,
"%u",&prim))!=1) stopflag=
true;
36907 if ((err = std::fscanf(nfile,
"%u%255[^\n] ",&i0,line))<2) {
36909 "load_off(): Failed to read primitive %u/%u from file '%s'.",
36911 nb_read,nb_primitives,filename?filename:
"(FILE*)");
36913 err = std::fscanf(nfile,
"%*[^\n] ");
36915 err = std::sscanf(line,
"%f%f%f",&c0,&c1,&c2);
36921 if ((err = std::fscanf(nfile,
"%u%u%255[^\n] ",&i0,&i1,line))<2) {
36923 "load_off(): Failed to read primitive %u/%u from file '%s'.",
36925 nb_read,nb_primitives,filename?filename:
"(FILE*)");
36927 err = std::fscanf(nfile,
"%*[^\n] ");
36929 err = std::sscanf(line,
"%f%f%f",&c0,&c1,&c2);
36935 if ((err = std::fscanf(nfile,
"%u%u%u%255[^\n] ",&i0,&i1,&i2,line))<3) {
36937 "load_off(): Failed to read primitive %u/%u from file '%s'.",
36939 nb_read,nb_primitives,filename?filename:
"(FILE*)");
36941 err = std::fscanf(nfile,
"%*[^\n] ");
36943 err = std::sscanf(line,
"%f%f%f",&c0,&c1,&c2);
36949 if ((err = std::fscanf(nfile,
"%u%u%u%u%255[^\n] ",&i0,&i1,&i2,&i3,line))<4) {
36951 "load_off(): Failed to read primitive %u/%u from file '%s'.",
36953 nb_read,nb_primitives,filename?filename:
"(FILE*)");
36955 err = std::fscanf(nfile,
"%*[^\n] ");
36957 err = std::sscanf(line,
"%f%f%f",&c0,&c1,&c2);
36963 if ((err = std::fscanf(nfile,
"%u%u%u%u%u%255[^\n] ",&i0,&i1,&i2,&i3,&i4,line))<5) {
36965 "load_off(): Failed to read primitive %u/%u from file '%s'.",
36967 nb_read,nb_primitives,filename?filename:
"(FILE*)");
36969 err = std::fscanf(nfile,
"%*[^\n] ");
36971 err = std::sscanf(line,
"%f%f%f",&c0,&c1,&c2);
36974 colors.
insert(2,CImg<tc>::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255)));
36979 if ((err = std::fscanf(nfile,
"%u%u%u%u%u%u%255[^\n] ",&i0,&i1,&i2,&i3,&i4,&i5,line))<6) {
36981 "load_off(): Failed to read primitive %u/%u from file '%s'.",
36983 nb_read,nb_primitives,filename?filename:
"(FILE*)");
36985 err = std::fscanf(nfile,
"%*[^\n] ");
36987 err = std::sscanf(line,
"%f%f%f",&c0,&c1,&c2);
36990 colors.
insert(2,CImg<tc>::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255)));
36995 if ((err = std::fscanf(nfile,
"%u%u%u%u%u%u%u%255[^\n] ",&i0,&i1,&i2,&i3,&i4,&i5,&i6,line))<7) {
36997 "load_off(): Failed to read primitive %u/%u from file '%s'.",
36999 nb_read,nb_primitives,filename?filename:
"(FILE*)");
37001 err = std::fscanf(nfile,
"%*[^\n] ");
37003 err = std::sscanf(line,
"%f%f%f",&c0,&c1,&c2);
37007 colors.
insert(3,CImg<tc>::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255)));
37008 ++(++nb_primitives);
37012 if ((err = std::fscanf(nfile,
"%u%u%u%u%u%u%u%u%255[^\n] ",&i0,&i1,&i2,&i3,&i4,&i5,&i6,&i7,line))<7) {
37014 "load_off(): Failed to read primitive %u/%u from file '%s'.",
37016 nb_read,nb_primitives,filename?filename:
"(FILE*)");
37018 err = std::fscanf(nfile,
"%*[^\n] ");
37020 err = std::sscanf(line,
"%f%f%f",&c0,&c1,&c2);
37024 colors.
insert(3,CImg<tc>::vector((tc)(c0*255),(tc)(c1*255),(tc)(c2*255)));
37025 ++(++nb_primitives);
37030 "load_off(): Failed to read primitive %u/%u (%u vertices) from file '%s'.",
37032 nb_read,nb_primitives,prim,filename?filename:
"(FILE*)");
37034 err = std::fscanf(nfile,
"%*[^\n] ");
37039 if (primitives._width!=nb_primitives)
37041 "load_off(): Only %u/%u primitives read from file '%s'.",
37043 primitives._width,nb_primitives,filename?filename:
"(FILE*)");
37069 "load_graphicsmagick_external(): Specified filename is (null).",
37072 char command[1024] = { 0 }, filetmp[512] = { 0 };
37073 std::FILE *file = 0;
37076 file = popen(command,
"r");
37078 try {
load_pnm(file); }
catch (...) {
37081 "load_graphicsmagick_external(): Failed to load file '%s' with external command 'gm'.",
37090 cimg_snprintf(filetmp,
sizeof(filetmp),
"%s%c%s.pnm",
cimg::temporary_path(),cimg_file_separator,cimg::filenamerand());
37091 if ((file=std::fopen(filetmp,
"rb"))!=0)
cimg::fclose(file);
37095 if (!(file = std::fopen(filetmp,
"rb"))) {
37098 "load_graphicsmagick_external(): Failed to load file '%s' with external command 'gm'.",
37104 std::remove(filetmp);
37120 "load_gzip_external(): Specified filename is (null).",
37123 char command[1024] = { 0 }, filetmp[512] = { 0 }, body[512] = { 0 };
37128 std::FILE *file = 0;
37131 if (*ext2) cimg_snprintf(filetmp,
sizeof(filetmp),
"%s%c%s.%s",
cimg::temporary_path(),cimg_file_separator,cimg::filenamerand(),ext2);
37132 else cimg_snprintf(filetmp,
sizeof(filetmp),
"%s%c%s",
cimg::temporary_path(),cimg_file_separator,cimg::filenamerand());
37134 if (*ext) cimg_snprintf(filetmp,
sizeof(filetmp),
"%s%c%s.%s",
cimg::temporary_path(),cimg_file_separator,cimg::filenamerand(),ext);
37135 else cimg_snprintf(filetmp,
sizeof(filetmp),
"%s%c%s",
cimg::temporary_path(),cimg_file_separator,cimg::filenamerand());
37137 if ((file=std::fopen(filetmp,
"rb"))!=0)
cimg::fclose(file);
37140 cimg_snprintf(command,
sizeof(command),
"%s -c \"%s\" > %s",
cimg::gunzip_path(),filename,filetmp);
37142 if (!(file = std::fopen(filetmp,
"rb"))) {
37145 "load_gzip_external(): Failed to load file '%s' with external command 'gunzip'.",
37151 std::remove(filetmp);
37167 "load_imagemagick_external(): Specified filename is (null).",
37170 char command[1024] = { 0 }, filetmp[512] = { 0 };
37171 std::FILE *file = 0;
37174 file = popen(command,
"r");
37176 try {
load_pnm(file); }
catch (...) {
37179 "load_imagemagick_external(): Failed to load file '%s' with external command 'convert'.",
37188 cimg_snprintf(filetmp,
sizeof(filetmp),
"%s%c%s.pnm",
cimg::temporary_path(),cimg_file_separator,cimg::filenamerand());
37189 if ((file=std::fopen(filetmp,
"rb"))!=0)
cimg::fclose(file);
37193 if (!(file = std::fopen(filetmp,
"rb"))) {
37196 "load_imagemagick_external(): Failed to load file '%s' with external command 'convert'.",
37202 std::remove(filetmp);
37218 "load_medcon_external(): Specified filename is (null).",
37221 char command[1024] = { 0 }, filetmp[512] = { 0 }, body[512] = { 0 };
37223 std::FILE *file = 0;
37225 cimg_snprintf(filetmp,
sizeof(filetmp),
"%s.hdr",cimg::filenamerand());
37226 if ((file=std::fopen(filetmp,
"rb"))!=0)
cimg::fclose(file);
37228 cimg_snprintf(command,
sizeof(command),
"%s -w -c anlz -o %s -f %s",
cimg::medcon_path(),filetmp,filename);
37232 cimg_snprintf(command,
sizeof(command),
"%s.hdr",body);
37233 file = std::fopen(command,
"rb");
37235 cimg_snprintf(command,
sizeof(command),
"m000-%s.hdr",body);
37236 file = std::fopen(command,
"rb");
37239 "load_medcon_external(): Failed to load file '%s' with external command 'medcon'.",
37246 std::remove(command);
37248 cimg_snprintf(command,
sizeof(command),
"%s.img",body);
37249 std::remove(command);
37265 "load_dcraw_external(): Specified filename is (null).",
37268 char command[1024] = { 0 }, filetmp[512] = { 0 };
37269 std::FILE *file = 0;
37271 cimg_snprintf(command,
sizeof(command),
"%s -w -4 -c \"%s\"",
cimg::dcraw_path(),filename);
37272 file = popen(command,
"r");
37274 try {
load_pnm(file); }
catch (...) {
37277 "load_dcraw_external(): Failed to load file '%s' with external command 'dcraw'.",
37286 cimg_snprintf(filetmp,
sizeof(filetmp),
"%s%c%s.ppm",
cimg::temporary_path(),cimg_file_separator,cimg::filenamerand());
37287 if ((file=std::fopen(filetmp,
"rb"))!=0)
cimg::fclose(file);
37289 cimg_snprintf(command,
sizeof(command),
"%s -w -4 -c \"%s\" > %s",
cimg::dcraw_path(),filename,filetmp);
37291 if (!(file = std::fopen(filetmp,
"rb"))) {
37294 "load_dcraw_external(): Failed to load file '%s' with external command 'dcraw'.",
37300 std::remove(filetmp);
37315 CImg<T>&
load_camera(
const int camera_index=-1,
const unsigned int skip_frames=0,
const bool release_camera=
false) {
37316 #ifdef cimg_use_opencv
37317 const int ind = camera_index + 1;
37318 if (ind<0 || ind>255)
37320 "load_camera(): Invalid request for camera #%d.",
37323 static CvCapture *capture[256] = { 0 };
37324 if (release_camera) {
37325 if (capture[ind]) cvReleaseCapture(&(capture[ind]));
37329 if (!capture[ind]) {
37330 capture[ind] = cvCreateCameraCapture(camera_index);
37331 if (!capture[ind]) {
37332 if (camera_index>=0)
37334 "load_camera(): Failed to initialize camera #%d.",
37339 "load_camera(): Failed to initialize default camera.",
37343 const IplImage *img = 0;
37344 for (
unsigned int i = 0; i<skip_frames; ++i) img = cvQueryFrame(capture[ind]);
37345 img = cvQueryFrame(capture[ind]);
37347 const int step = (int)(img->widthStep - 3*img->width);
37348 assign(img->width,img->height,1,3);
37349 const unsigned char* ptrs = (
unsigned char*)img->imageData;
37350 T *ptr_r =
data(0,0,0,0), *ptr_g =
data(0,0,0,1), *ptr_b =
data(0,0,0,2);
37351 if (step>0) cimg_forY(*
this,y) {
37352 cimg_forX(*
this,x) { *(ptr_b++) = (T)*(ptrs++); *(ptr_g++) = (T)*(ptrs++); *(ptr_r++) = (T)*(ptrs++); }
37354 }
else for (
unsigned long siz = (
unsigned long)img->width*img->height; siz; --siz) {
37355 *(ptr_b++) = (T)*(ptrs++); *(ptr_g++) = (T)*(ptrs++); *(ptr_r++) = (T)*(ptrs++);
37359 cimg::unused(camera_index,skip_frames,release_camera);
37361 "load_camera(): This function requires the OpenCV library to run "
37362 "(macro 'cimg_use_opencv' must be defined).",
37380 "load_other(): Specified filename is (null).",
37397 "load_other(): Failed to recognize format of file '%s'.",
37403 "load_other(): Failed to open file '%s'.",
37432 const CImg<T>&
print(
const char *
const title=0,
const bool display_stats=
true)
const {
37433 int xm = 0, ym = 0, zm = 0, vm = 0, xM = 0, yM = 0, zM = 0, vM = 0;
37435 if (!
is_empty() && display_stats) {
37437 xm = (int)st[4]; ym = (int)st[5], zm = (
int)st[6], vm = (int)st[7];
37438 xM = (int)st[8]; yM = (int)st[9], zM = (
int)st[10], vM = (int)st[11];
37440 const unsigned long siz =
size(), msiz = siz*
sizeof(T), siz1 = siz-1, mdisp = msiz<8*1024?0:(msiz<8*1024*1024?1:2), width1 = _width-1;
37442 char _title[64] = { 0 };
37443 if (!title) cimg_snprintf(_title,
sizeof(_title),
"CImg<%s>",
pixel_type());
37445 std::fprintf(
cimg::output(),
"%s%s%s%s: %sthis%s = %p, %ssize%s = (%u,%u,%u,%u) [%lu %s], %sdata%s = (%s*)%p",
37446 cimg::t_magenta,cimg::t_bold,title?title:_title,cimg::t_normal,
37447 cimg::t_bold,cimg::t_normal,(
void*)
this,
37448 cimg::t_bold,cimg::t_normal,_width,_height,_depth,_spectrum,
37449 mdisp==0?msiz:(mdisp==1?(msiz>>10):(msiz>>20)),
37450 mdisp==0?
"b":(mdisp==1?
"Kio":
"Mio"),
37452 if (_data) std::fprintf(
cimg::output(),
"..%p (%s) = [ ",(
void*)((
char*)
end()-1),_is_shared?
"shared":
"non-shared");
37453 else std::fprintf(
cimg::output(),
" (%s) = [ ",_is_shared?
"shared":
"non-shared");
37455 if (!
is_empty()) cimg_foroff(*
this,off) {
37457 if (off!=siz1) std::fprintf(
cimg::output(),
"%s",off%_width==width1?
" ; ":
" ");
37458 if (off==7 && siz>16) { off = siz1-8;
if (off!=7) std::fprintf(
cimg::output(),
"... "); }
37461 std::fprintf(
cimg::output(),
" ], %smin%s = %g, %smax%s = %g, %smean%s = %g, %sstd%s = %g, %scoords_min%s = (%u,%u,%u,%u), %scoords_max%s = (%u,%u,%u,%u).\n",
37462 cimg::t_bold,cimg::t_normal,st[0],
37463 cimg::t_bold,cimg::t_normal,st[1],
37464 cimg::t_bold,cimg::t_normal,st[2],
37465 cimg::t_bold,cimg::t_normal,std::sqrt(st[3]),
37466 cimg::t_bold,cimg::t_normal,xm,ym,zm,vm,
37467 cimg::t_bold,cimg::t_normal,xM,yM,zM,vM);
37488 return _display(disp,0,display_info,XYZ,
false);
37496 const CImg<T>&
display(
const char *
const title=0,
const bool display_info=
true,
unsigned int *
const XYZ=0)
const {
37498 return _display(disp,title,display_info,XYZ,
false);
37502 const bool display_info,
unsigned int *
const XYZ,
37503 const bool exit_on_simpleclick)
const {
37506 "display(): Empty instance.",
37509 unsigned int oldw = 0, oldh = 0, _XYZ[3], key = 0;
37510 int x0 = 0, y0 = 0, z0 = 0, x1 =
width() - 1, y1 =
height() - 1, z1 =
depth() - 1;
37513 disp.
assign(cimg_fitscreen(_width,_height,_depth),title?title:0,1);
37514 if (!title) disp.
set_title(
"CImg<%s> (%ux%ux%ux%u)",
pixel_type(),_width,_height,_depth,_spectrum);
37515 }
else if (title) disp.
set_title(
"%s",title);
37519 if (display_info)
print(dtitle);
37522 for (
bool reset_view =
true, resize_disp =
false, is_first_select =
true; !key && !disp.
is_closed(); ) {
37524 if (XYZ) { _XYZ[0] = XYZ[0]; _XYZ[1] = XYZ[1]; _XYZ[2] = XYZ[2]; }
37525 else { _XYZ[0] = (x0 + x1)/2; _XYZ[1] = (y0 + y1)/2; _XYZ[2] = (z0 + z1)/2; }
37526 x0 = 0; y0 = 0; z0 = 0; x1 = _width - 1; y1 = _height-1; z1 = _depth-1;
37528 reset_view =
false;
37530 if (!x0 && !y0 && !z0 && x1==
width()-1 && y1==
height()-1 && z1==
depth()-1) zoom.assign();
37531 else zoom =
get_crop(x0,y0,z0,x1,y1,z1);
37534 dx = 1 + x1 - x0, dy = 1 + y1 - y0, dz = 1 + z1 - z0,
37535 tw = dx + (dz>1?dz:0), th = dy + (dz>1?dz:0);
37538 ttw = tw*disp.
width()/oldw, tth = th*disp.
height()/oldh,
37542 resize_disp =
false;
37544 oldw = tw; oldh = th;
37547 go_up =
false, go_down =
false, go_left =
false, go_right =
false,
37548 go_inc =
false, go_dec =
false, go_in =
false, go_out =
false,
37549 go_in_center =
false;
37550 const CImg<T>& visu = zoom?zoom:*
this;
37551 const CImg<intT> selection = visu._get_select(disp,0,2,_XYZ,x0,y0,z0,is_first_select);
37552 is_first_select =
false;
37554 if (disp.
wheel()) {
37555 if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { go_out = !(go_in = disp.
wheel()>0); go_in_center =
false; }
37556 else if (disp.is_keySHIFTLEFT() || disp.is_keySHIFTRIGHT()) { go_right = !(go_left = disp.
wheel()>0); }
37557 else if (disp.is_keyALT() || disp.is_keyALTGR() || _depth==1) { go_down = !(go_up = disp.
wheel()>0); }
37562 sx0 = selection(0), sy0 = selection(1), sz0 = selection(2),
37563 sx1 = selection(3), sy1 = selection(4), sz1 = selection(5);
37564 if (sx0>=0 && sy0>=0 && sz0>=0 && sx1>=0 && sy1>=0 && sz1>=0) {
37565 x1 = x0 + sx1; y1 = y0 + sy1; z1 = z0 + sz1; x0+=sx0; y0+=sy0; z0+=sz0;
37566 if (sx0==sx1 && sy0==sy1 && sz0==sz1) {
37567 if (exit_on_simpleclick && !zoom)
break;
else reset_view =
true;
37569 resize_disp =
true;
37570 }
else switch (key = disp.
key()) {
37579 case cimg::keyP :
if (visu._depth>1 && (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT())) {
37581 w1 = visu._width*disp.
width()/(visu._width+(visu._depth>1?visu._depth:0)),
37582 h1 = visu._height*disp.
height()/(visu._height+(visu._depth>1?visu._depth:0));
37583 float frame_timing = 5;
37584 bool is_stopped =
false;
37586 for (
unsigned int timer = 0; !key && !disp.
is_closed() && !disp.
button(); ) {
37589 visu.get_slice((
int)_XYZ[2]).display(disp.
set_title(
"%s | z=%d",dtitle.data(),_XYZ[2]));
37590 (++_XYZ[2])%=visu._depth;
37592 if (!is_stopped) {
if (++timer>(
unsigned int)frame_timing) timer = 0; }
else timer = ~0U;
37594 switch (key = disp.
key()) {
37604 case cimg::keyD : if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
37606 CImgDisplay::_fitscreen(3*disp.
width()/2,3*disp.
height()/2,1,128,-100,
true),
false);
37607 disp.
set_key(key,
false); key = 0;
37609 case cimg::keyC :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
37612 case cimg::keyR :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
37615 case cimg::keyF :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
37619 frame_timing = frame_timing<1?1:(frame_timing>39?39:frame_timing);
37623 w2 = (visu._width + (visu._depth>1?visu._depth:0))*disp.
width()/visu._width,
37624 h2 = (visu._height + (visu._depth>1?visu._depth:0))*disp.
height()/visu._height;
37628 case cimg::keyHOME : reset_view = resize_disp =
true; key = 0;
break;
37629 case cimg::keyPADADD : go_in =
true; go_in_center =
true; key = 0;
break;
37635 case cimg::keyPAD7 : go_up = go_left =
true; key = 0;
break;
37636 case cimg::keyPAD9 : go_up = go_right =
true; key = 0;
break;
37637 case cimg::keyPAD1 : go_down = go_left =
true; key = 0;
break;
37638 case cimg::keyPAD3 : go_down = go_right =
true; key = 0;
break;
37646 mX = mx*(_width+(_depth>1?_depth:0))/disp.
width(),
37647 mY = my*(_height+(_depth>1?_depth:0))/disp.
height();
37648 int X = _XYZ[0], Y = _XYZ[1], Z = _XYZ[2];
37649 if (mX<
width() && mY<
height()) { X = x0 + mX*(1+x1-x0)/_width; Y = y0 + mY*(1+y1-y0)/_height; Z = _XYZ[2]; }
37650 if (mX<
width() && mY>=
height()) { X = x0 + mX*(1+x1-x0)/_width; Z = z0 + (mY-_height)*(1+z1-z0)/_depth; Y = _XYZ[1]; }
37651 if (mX>=
width() && mY<
height()) { Y = y0 + mY*(1+y1-y0)/_height; Z = z0 + (mX-_width)*(1+z1-z0)/_depth; X = _XYZ[0]; }
37652 if (x1-x0>4) { x0 = X - 7*(X-x0)/8; x1 = X + 7*(x1-X)/8; }
37653 if (y1-y0>4) { y0 = Y - 7*(Y-y0)/8; y1 = Y + 7*(y1-Y)/8; }
37654 if (z1-z0>4) { z0 = Z - 7*(Z-z0)/8; z1 = Z + 7*(z1-Z)/8; }
37658 delta_x = (x1-x0)/8, delta_y = (y1-y0)/8, delta_z = (z1-z0)/8,
37659 ndelta_x = delta_x?delta_x:(_width>1?1:0),
37660 ndelta_y = delta_y?delta_y:(_height>1?1:0),
37661 ndelta_z = delta_z?delta_z:(_depth>1?1:0);
37662 x0-=ndelta_x; y0-=ndelta_y; z0-=ndelta_z;
37663 x1+=ndelta_x; y1+=ndelta_y; z1+=ndelta_z;
37664 if (x0<0) { x1-=x0; x0 = 0;
if (x1>=
width()) x1 =
width() - 1; }
37665 if (y0<0) { y1-=y0; y0 = 0;
if (y1>=
height()) y1 =
height() - 1; }
37666 if (z0<0) { z1-=z0; z0 = 0;
if (z1>=
depth()) z1 =
depth() - 1; }
37667 if (x1>=
width()) { x0-=(x1-
width()+1); x1 =
width()-1;
if (x0<0) x0 = 0; }
37669 if (z1>=
depth()) { z0-=(z1-
depth()+1); z1 =
depth()-1;
if (z0<0) z0 = 0; }
37672 const int delta = (x1-x0)/5, ndelta = delta?delta:(_width>1?1:0);
37673 if (x0-ndelta>=0) { x0-=ndelta; x1-=ndelta; }
37674 else { x1-=x0; x0 = 0; }
37677 const int delta = (x1-x0)/5, ndelta = delta?delta:(_width>1?1:0);
37678 if (x1+ndelta<
width()) { x0+=ndelta; x1+=ndelta; }
37679 else { x0+=(
width()-1-x1); x1 =
width()-1; }
37682 const int delta = (y1-y0)/5, ndelta = delta?delta:(_height>1?1:0);
37683 if (y0-ndelta>=0) { y0-=ndelta; y1-=ndelta; }
37684 else { y1-=y0; y0 = 0; }
37687 const int delta = (y1-y0)/5, ndelta = delta?delta:(_height>1?1:0);
37688 if (y1+ndelta<
height()) { y0+=ndelta; y1+=ndelta; }
37692 const int delta = (z1-z0)/5, ndelta = delta?delta:(_depth>1?1:0);
37693 if (z0-ndelta>=0) { z0-=ndelta; z1-=ndelta; }
37694 else { z1-=z0; z0 = 0; }
37697 const int delta = (z1-z0)/5, ndelta = delta?delta:(_depth>1?1:0);
37698 if (z1+ndelta<
depth()) { z0+=ndelta; z1+=ndelta; }
37699 else { z0+=(
depth()-1-z1); z1 =
depth()-1; }
37704 if (XYZ) { XYZ[0] = _XYZ[0]; XYZ[1] = _XYZ[1]; XYZ[2] = _XYZ[2]; }
37728 template<
typename tp,
typename tf,
typename tc,
typename to>
37733 const to& opacities,
37734 const bool centering=
true,
37735 const int render_static=4,
const int render_motion=1,
37736 const bool is_double_sided=
true,
const float focale=500,
37737 const float light_x=0,
const float light_y=0,
const float light_z=-5000,
37738 const float specular_lightness=0.2f,
const float specular_shininess=0.1f,
37739 const bool display_axes=
true,
float *
const pose_matrix=0)
const {
37740 return _display_object3d(disp,0,vertices,primitives,colors,opacities,centering,render_static,
37741 render_motion,is_double_sided,focale,
37742 light_x,light_y,light_z,specular_lightness,specular_shininess,
37743 display_axes,pose_matrix);
37747 template<
typename tp,
typename tf,
typename tc,
typename to>
37752 const to& opacities,
37753 const bool centering=
true,
37754 const int render_static=4,
const int render_motion=1,
37755 const bool is_double_sided=
true,
const float focale=500,
37756 const float light_x=0,
const float light_y=0,
const float light_z=-5000,
37757 const float specular_lightness=0.2f,
const float specular_shininess=0.1f,
37758 const bool display_axes=
true,
float *
const pose_matrix=0)
const {
37760 return _display_object3d(disp,title,vertices,primitives,colors,opacities,centering,render_static,
37761 render_motion,is_double_sided,focale,
37762 light_x,light_y,light_z,specular_lightness,specular_shininess,
37763 display_axes,pose_matrix);
37767 template<
typename tp,
typename tf,
typename tc>
37772 const bool centering=
true,
37773 const int render_static=4,
const int render_motion=1,
37774 const bool is_double_sided=
true,
const float focale=500,
37775 const float light_x=0,
const float light_y=0,
const float light_z=-5000,
37776 const float specular_lightness=0.2f,
const float specular_shininess=0.1f,
37777 const bool display_axes=
true,
float *
const pose_matrix=0)
const {
37779 render_static,render_motion,is_double_sided,focale,
37780 light_x,light_y,light_z,specular_lightness,specular_shininess,
37781 display_axes,pose_matrix);
37785 template<
typename tp,
typename tf,
typename tc>
37790 const bool centering=
true,
37791 const int render_static=4,
const int render_motion=1,
37792 const bool is_double_sided=
true,
const float focale=500,
37793 const float light_x=0,
const float light_y=0,
const float light_z=-5000,
37794 const float specular_lightness=0.2f,
const float specular_shininess=0.1f,
37795 const bool display_axes=
true,
float *
const pose_matrix=0)
const {
37797 render_static,render_motion,is_double_sided,focale,
37798 light_x,light_y,light_z,specular_lightness,specular_shininess,
37799 display_axes,pose_matrix);
37803 template<
typename tp,
typename tf>
37807 const bool centering=
true,
37808 const int render_static=4,
const int render_motion=1,
37809 const bool is_double_sided=
true,
const float focale=500,
37810 const float light_x=0,
const float light_y=0,
const float light_z=-5000,
37811 const float specular_lightness=0.2f,
const float specular_shininess=0.1f,
37812 const bool display_axes=
true,
float *
const pose_matrix=0)
const {
37814 render_static,render_motion,is_double_sided,focale,
37815 light_x,light_y,light_z,specular_lightness,specular_shininess,
37816 display_axes,pose_matrix);
37821 template<
typename tp,
typename tf>
37825 const bool centering=
true,
37826 const int render_static=4,
const int render_motion=1,
37827 const bool is_double_sided=
true,
const float focale=500,
37828 const float light_x=0,
const float light_y=0,
const float light_z=-5000,
37829 const float specular_lightness=0.2f,
const float specular_shininess=0.1f,
37830 const bool display_axes=
true,
float *
const pose_matrix=0)
const {
37832 render_static,render_motion,is_double_sided,focale,
37833 light_x,light_y,light_z,specular_lightness,specular_shininess,
37834 display_axes,pose_matrix);
37838 template<
typename tp>
37841 const bool centering=
true,
37842 const int render_static=4,
const int render_motion=1,
37843 const bool is_double_sided=
true,
const float focale=500,
37844 const float light_x=0,
const float light_y=0,
const float light_z=-5000,
37845 const float specular_lightness=0.2f,
const float specular_shininess=0.1f,
37846 const bool display_axes=
true,
float *
const pose_matrix=0)
const {
37848 render_static,render_motion,is_double_sided,focale,
37849 light_x,light_y,light_z,specular_lightness,specular_shininess,
37850 display_axes,pose_matrix);
37854 template<
typename tp>
37857 const bool centering=
true,
37858 const int render_static=4,
const int render_motion=1,
37859 const bool is_double_sided=
true,
const float focale=500,
37860 const float light_x=0,
const float light_y=0,
const float light_z=-5000,
37861 const float specular_lightness=0.2f,
const float specular_shininess=0.1f,
37862 const bool display_axes=
true,
float *
const pose_matrix=0)
const {
37864 render_static,render_motion,is_double_sided,focale,
37865 light_x,light_y,light_z,specular_lightness,specular_shininess,
37866 display_axes,pose_matrix);
37869 template<
typename tp,
typename tf,
typename tc,
typename to>
37874 const to& opacities,
37875 const bool centering,
37876 const int render_static,
const int render_motion,
37877 const bool is_double_sided,
const float focale,
37878 const float light_x,
const float light_y,
const float light_z,
37879 const float specular_lightness,
const float specular_shininess,
37880 const bool display_axes,
float *
const pose_matrix)
const {
37881 typedef typename cimg::superset<tp,float>::type tpfloat;
37886 _display_object3d(disp,title,vertices,primitives,colors,opacities,centering,
37887 render_static,render_motion,is_double_sided,focale,
37888 light_x,light_y,light_z,specular_lightness,specular_shininess,
37889 display_axes,pose_matrix);
37890 else return CImg<T>(1,2,1,1,64,128).
resize(cimg_fitscreen(640,480,1),1,(colors && colors[0].
size()==1)?1:3,3).
37891 _display_object3d(disp,title,vertices,primitives,colors,opacities,centering,
37892 render_static,render_motion,is_double_sided,focale,
37893 light_x,light_y,light_z,specular_lightness,specular_shininess,
37894 display_axes,pose_matrix);
37895 }
else {
if (disp) disp.
resize(*
this,
false); }
37896 char error_message[1024] = { 0 };
37897 if (!vertices.is_object3d(primitives,colors,opacities,
true,error_message))
37898 throw CImgArgumentException(_cimg_instance
37899 "display_object3d(): Invalid specified 3d object (%u,%u) (%s).",
37900 cimg_instance,vertices._width,primitives._width,error_message);
37901 if (vertices._width && !primitives) {
37902 CImgList<tf> nprimitives(vertices._width,1,1,1,1);
37903 cimglist_for(nprimitives,l) nprimitives(l,0) = l;
37904 return _display_object3d(disp,title,vertices,nprimitives,colors,opacities,centering,
37905 render_static,render_motion,is_double_sided,focale,
37906 light_x,light_y,light_z,specular_lightness,specular_shininess,
37907 display_axes,pose_matrix);
37910 disp.assign(cimg_fitscreen(_width,_height,_depth),title?title:0,3);
37911 if (!title) disp.set_title(
"CImg<%s> (%u vertices, %u primitives)",
pixel_type(),vertices._width,primitives._width);
37912 }
else if (title) disp.set_title(
"%s",title);
37917 rotated_vertices(vertices._width,3),
37918 bbox_vertices, rotated_bbox_vertices,
37919 axes_vertices, rotated_axes_vertices,
37920 bbox_opacities, axes_opacities;
37921 CImgList<uintT> bbox_primitives, axes_primitives;
37922 CImgList<tf> reverse_primitives;
37923 CImgList<T> bbox_colors, bbox_colors2, axes_colors;
37924 unsigned int ns_width = 0, ns_height = 0;
37925 int _is_double_sided = (int)is_double_sided;
37926 bool ndisplay_axes = display_axes;
37928 background_color(1,1,1,_spectrum,0),
37929 foreground_color(1,1,1,_spectrum,255);
37931 Xoff = 0, Yoff = 0, Zoff = 0, sprite_scale = 1,
37932 xm = 0, xM = vertices?vertices.get_shared_row(0).max_min(xm):0,
37933 ym = 0, yM = vertices?vertices.get_shared_row(1).max_min(ym):0,
37934 zm = 0, zM = vertices?vertices.get_shared_row(2).max_min(zm):0;
37935 const float delta =
cimg::max(xM-xm,yM-ym,zM-zm);
37937 rotated_bbox_vertices = bbox_vertices.assign(8,3,1,1,
37938 xm,xM,xM,xm,xm,xM,xM,xm,
37939 ym,ym,yM,yM,ym,ym,yM,yM,
37940 zm,zm,zm,zm,zM,zM,zM,zM);
37941 bbox_primitives.assign(6,1,4,1,1, 0,3,2,1, 4,5,6,7, 1,2,6,5, 0,4,7,3, 0,1,5,4, 2,3,7,6);
37942 bbox_colors.assign(6,_spectrum,1,1,1,background_color[0]);
37943 bbox_colors2.assign(6,_spectrum,1,1,1,foreground_color[0]);
37944 bbox_opacities.assign(bbox_colors._width,1,1,1,0.3f);
37946 rotated_axes_vertices = axes_vertices.assign(7,3,1,1,
37950 axes_opacities.assign(3,1,1,1,1);
37951 axes_colors.assign(3,_spectrum,1,1,1,foreground_color[0]);
37952 axes_primitives.assign(3,1,2,1,1, 0,1, 0,2, 0,3);
37955 CImg<T> visu0(*
this), visu;
37956 CImg<tpfloat> zbuffer(visu0.width(),visu0.height(),1,1,0);
37957 bool init_pose =
true, clicked =
false, redraw =
true;
37958 unsigned int key = 0;
37960 x0 = 0, y0 = 0, x1 = 0, y1 = 0,
37961 nrender_static = render_static,
37962 nrender_motion = render_motion;
37963 disp.show().flush();
37965 while (!disp.is_closed() && !key) {
37970 ratio = delta>0?(2.0f*
cimg::min(disp.width(),disp.height())/(3.0f*delta)):1,
37971 dx = (xM + xm)/2, dy = (yM + ym)/2, dz = (zM + zm)/2;
37973 CImg<floatT>(4,3,1,1, ratio,0.,0.,-ratio*dx, 0.,ratio,0.,-ratio*dy, 0.,0.,ratio,-ratio*dz).
move_to(pose);
37974 else CImg<floatT>(4,3,1,1, 1,0,0,0, 0,1,0,0, 0,0,1,0).
move_to(pose);
37976 CImg<floatT> pose0(pose_matrix,4,3,1,1,
false);
37977 pose0.resize(4,4,1,1,0); pose.resize(4,4,1,1,0);
37978 pose0(3,3) = pose(3,3) = 1;
37979 (pose0*pose).
get_crop(0,0,3,2).move_to(pose);
37980 Xoff = pose_matrix[12]; Yoff = pose_matrix[13]; Zoff = pose_matrix[14]; sprite_scale = pose_matrix[15];
37981 }
else { Xoff = Yoff = Zoff = 0; sprite_scale = 1; }
37989 r00 = pose(0,0), r10 = pose(1,0), r20 = pose(2,0), r30 = pose(3,0),
37990 r01 = pose(0,1), r11 = pose(1,1), r21 = pose(2,1), r31 = pose(3,1),
37991 r02 = pose(0,2), r12 = pose(1,2), r22 = pose(2,2), r32 = pose(3,2);
37992 if ((clicked && nrender_motion>=0) || (!clicked && nrender_static>=0))
37993 cimg_forX(vertices,l) {
37994 const float x = (float)vertices(l,0), y = (float)vertices(l,1), z = (float)vertices(l,2);
37995 rotated_vertices(l,0) = r00*x + r10*y + r20*z + r30;
37996 rotated_vertices(l,1) = r01*x + r11*y + r21*z + r31;
37997 rotated_vertices(l,2) = r02*x + r12*y + r22*z + r32;
37999 else cimg_forX(bbox_vertices,l) {
38000 const float x = bbox_vertices(l,0), y = bbox_vertices(l,1), z = bbox_vertices(l,2);
38001 rotated_bbox_vertices(l,0) = r00*x + r10*y + r20*z + r30;
38002 rotated_bbox_vertices(l,1) = r01*x + r11*y + r21*z + r31;
38003 rotated_bbox_vertices(l,2) = r02*x + r12*y + r22*z + r32;
38008 if ((clicked && nrender_motion<0) || (!clicked && nrender_static<0))
38009 visu.draw_object3d(Xoff + visu._width/2.0f,Yoff + visu._height/2.0f,Zoff,
38010 rotated_bbox_vertices,bbox_primitives,bbox_colors,bbox_opacities,2,
false,focale).
38011 draw_object3d(Xoff + visu._width/2.0f,Yoff + visu._height/2.0f,Zoff,
38012 rotated_bbox_vertices,bbox_primitives,bbox_colors2,1,
false,focale);
38013 else visu._draw_object3d((
void*)0,(!clicked && nrender_static>0)?zbuffer.fill(0):
CImg<tpfloat>::empty(),
38014 Xoff + visu._width/2.0f,Yoff + visu._height/2.0f,Zoff,
38015 rotated_vertices,reverse_primitives?reverse_primitives:primitives,
38016 colors,opacities,clicked?nrender_motion:nrender_static,_is_double_sided==1,focale,
38017 width()/2.0f+light_x,
height()/2.0f+light_y,light_z,specular_lightness,specular_shininess,
38020 if (ndisplay_axes) {
38022 n = (float)std::sqrt(1e-8 + r00*r00 + r01*r01 + r02*r02),
38023 _r00 = r00/n, _r10 = r10/n, _r20 = r20/n,
38024 _r01 = r01/n, _r11 = r11/n, _r21 = r21/n,
38025 _r02 = r01/n, _r12 = r12/n, _r22 = r22/n,
38026 Xaxes = 25, Yaxes = visu._height - 38.0f;
38027 cimg_forX(axes_vertices,l) {
38029 x = axes_vertices(l,0),
38030 y = axes_vertices(l,1),
38031 z = axes_vertices(l,2);
38032 rotated_axes_vertices(l,0) = _r00*x + _r10*y + _r20*z;
38033 rotated_axes_vertices(l,1) = _r01*x + _r11*y + _r21*z;
38034 rotated_axes_vertices(l,2) = _r02*x + _r12*y + _r22*z;
38036 axes_opacities(0,0) = (rotated_axes_vertices(1,2)>0)?0.5f:1.0f;
38037 axes_opacities(1,0) = (rotated_axes_vertices(2,2)>0)?0.5f:1.0f;
38038 axes_opacities(2,0) = (rotated_axes_vertices(3,2)>0)?0.5f:1.0f;
38039 visu.draw_object3d(Xaxes,Yaxes,0,rotated_axes_vertices,axes_primitives,axes_colors,axes_opacities,1,
false,focale).
38040 draw_text((
int)(Xaxes+rotated_axes_vertices(4,0)),
38041 (
int)(Yaxes+rotated_axes_vertices(4,1)),
38042 "X",axes_colors[0]._data,0,axes_opacities(0,0),13).
38043 draw_text((
int)(Xaxes+rotated_axes_vertices(5,0)),
38044 (
int)(Yaxes+rotated_axes_vertices(5,1)),
38045 "Y",axes_colors[1]._data,0,axes_opacities(1,0),13).
38046 draw_text((
int)(Xaxes+rotated_axes_vertices(6,0)),
38047 (
int)(Yaxes+rotated_axes_vertices(6,1)),
38048 "Z",axes_colors[2]._data,0,axes_opacities(2,0),13);
38050 visu.display(disp);
38051 if (!clicked || nrender_motion==nrender_static) redraw =
false;
38056 if ((disp.button() || disp.wheel()) && disp.mouse_x()>=0 && disp.mouse_y()>=0) {
38058 if (!clicked) { x0 = x1 = disp.mouse_x(); y0 = y1 = disp.mouse_y();
if (!disp.wheel()) clicked =
true; }
38059 else { x1 = disp.mouse_x(); y1 = disp.mouse_y(); }
38060 if (disp.button()&1) {
38062 R = 0.45f*
cimg::min(disp.width(),disp.height()),
38064 u0 = (
float)(x0-disp.width()/2),
38065 v0 = (
float)(y0-disp.height()/2),
38066 u1 = (
float)(x1-disp.width()/2),
38067 v1 = (
float)(y1-disp.height()/2),
38068 n0 = (
float)std::sqrt(u0*u0+v0*v0),
38069 n1 = (float)std::sqrt(u1*u1+v1*v1),
38070 nu0 = n0>R?(u0*R/n0):u0,
38071 nv0 = n0>R?(v0*R/n0):v0,
38072 nw0 = (float)std::
sqrt(cimg::
max(0,R2-nu0*nu0-nv0*nv0)),
38073 nu1 = n1>R?(u1*R/n1):u1,
38074 nv1 = n1>R?(v1*R/n1):v1,
38075 nw1 = (float)std::
sqrt(cimg::
max(0,R2-nu1*nu1-nv1*nv1)),
38076 u = nv0*nw1-nw0*nv1,
38077 v = nw0*nu1-nu0*nw1,
38078 w = nv0*nu1-nu0*nv1,
38079 n = (float)std::
sqrt(u*u+v*v+w*w),
38080 alpha = (float)std::
asin(n/R2);
38084 if (disp.button()&2) {
38085 if (focale>0) Zoff-=(y0-y1)*focale/400;
38086 else {
const float s = std::exp((y0-y1)/400.0f); pose*=s; sprite_scale*=s; }
38089 if (disp.wheel()) {
38090 if (focale>0) Zoff-=disp.wheel()*focale/20;
38091 else {
const float s = std::exp(disp.wheel()/20.0f); pose*=s; sprite_scale*=s; }
38094 if (disp.button()&4) { Xoff+=(x1-x0); Yoff+=(y1-y0); x0 = x1; y0 = y1; }
38095 if ((disp.button()&1) && (disp.button()&2)) {
38096 init_pose =
true; disp.set_button(); x0 = x1; y0 = y1;
38097 pose = CImg<floatT>(4,3,1,1, 1,0,0,0, 0,1,0,0, 0,0,1,0);
38099 }
else if (clicked) { x0 = x1; y0 = y1; clicked =
false; redraw =
true; }
38101 switch (key = disp.key()) {
38106 case cimg::keyD:
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
38107 disp.set_fullscreen(
false).resize(CImgDisplay::_fitscreen(3*disp.width()/2,3*disp.height()/2,1,128,-100,
false),
38108 CImgDisplay::_fitscreen(3*disp.width()/2,3*disp.height()/2,1,128,-100,
true),
false).
38109 _is_resized =
true;
38110 disp.set_key(key,
false); key = 0;
38112 case cimg::keyC :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
38113 disp.set_fullscreen(
false).resize(cimg_fitscreen(2*disp.width()/3,2*disp.height()/3,1),
false)._is_resized =
true;
38114 disp.set_key(key,
false); key = 0;
38116 case cimg::keyR :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
38117 disp.set_fullscreen(
false).resize(cimg_fitscreen(_width,_height,_depth),
false)._is_resized =
true;
38118 disp.set_key(key,
false); key = 0;
38120 case cimg::keyF :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
38121 if (!ns_width || !ns_height ||
38122 ns_width>(
unsigned int)disp.screen_width() || ns_height>(
unsigned int)disp.screen_height()) {
38123 ns_width = disp.screen_width()*3U/4;
38124 ns_height = disp.screen_height()*3U/4;
38126 if (disp.is_fullscreen()) disp.resize(ns_width,ns_height,
false);
38128 ns_width = (
unsigned int)disp.width(); ns_height = disp.height();
38129 disp.resize(disp.screen_width(),disp.screen_height(),
false);
38131 disp.toggle_fullscreen()._is_resized =
true;
38132 disp.set_key(key,
false); key = 0;
38134 case cimg::keyT :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
38135 if (--_is_double_sided==-2) _is_double_sided = 1;
38136 if (_is_double_sided>=0) reverse_primitives.assign();
38138 disp.set_key(key,
false); key = 0; redraw =
true;
38140 case cimg::keyZ :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
38141 if (zbuffer) zbuffer.assign();
38142 else zbuffer.assign(visu0.width(),visu0.height(),1,1,0);
38143 disp.set_key(key,
false); key = 0; redraw =
true;
38145 case cimg::keyA :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
38146 ndisplay_axes = !ndisplay_axes;
38147 disp.set_key(key,
false); key = 0; redraw =
true;
38149 case cimg::keyF1 :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
38150 nrender_motion = (nrender_static==0 && nrender_motion!=0)?0:-1; nrender_static = 0;
38151 disp.set_key(key,
false); key = 0; redraw =
true;
38153 case cimg::keyF2 :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
38154 nrender_motion = (nrender_static==1 && nrender_motion!=1)?1:-1; nrender_static = 1;
38155 disp.set_key(key,
false); key = 0; redraw =
true;
38157 case cimg::keyF3 :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
38158 nrender_motion = (nrender_static==2 && nrender_motion!=2)?2:-1; nrender_static = 2;
38159 disp.set_key(key,
false); key = 0; redraw =
true;
38161 case cimg::keyF4 :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
38162 nrender_motion = (nrender_static==3 && nrender_motion!=3)?3:-1; nrender_static = 3;
38163 disp.set_key(key,
false); key = 0; redraw =
true;
38165 case cimg::keyF5 :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
38166 nrender_motion = (nrender_static==4 && nrender_motion!=4)?4:-1; nrender_static = 4;
38167 disp.set_key(key,
false); key = 0; redraw =
true;
38169 case cimg::keyF6 :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
38170 nrender_motion = (nrender_static==5 && nrender_motion!=5)?5:-1; nrender_static = 5;
38171 disp.set_key(key,
false); key = 0; redraw =
true;
38173 case cimg::keyS :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
38174 static unsigned int snap_number = 0;
38175 char filename[32] = { 0 };
38178 cimg_snprintf(filename,
sizeof(filename),cimg_appname
"_%.4u.bmp",snap_number++);
38179 if ((file=std::fopen(filename,
"r"))!=0)
cimg::fclose(file);
38181 (+visu).
draw_text(0,0,
" Saving snapshot... ",foreground_color._data,background_color._data,1,13).display(disp);
38182 visu.save(filename);
38183 visu.draw_text(0,0,
" Snapshot '%s' saved. ",foreground_color._data,background_color._data,1,13,filename).display(disp);
38184 disp.set_key(key,
false); key = 0;
38186 case cimg::keyG :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
38187 static unsigned int snap_number = 0;
38188 char filename[32] = { 0 };
38191 cimg_snprintf(filename,
sizeof(filename),cimg_appname
"_%.4u.off",snap_number++);
38192 if ((file=std::fopen(filename,
"r"))!=0)
cimg::fclose(file);
38194 visu.draw_text(0,0,
" Saving object... ",foreground_color._data,background_color._data,1,13).display(disp);
38195 vertices.save_off(reverse_primitives?reverse_primitives:primitives,colors,filename);
38196 visu.draw_text(0,0,
" Object '%s' saved. ",foreground_color._data,background_color._data,1,13,filename).display(disp);
38197 disp.set_key(key,
false); key = 0;
38199 case cimg::keyO :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
38200 static unsigned int snap_number = 0;
38201 char filename[32] = { 0 };
38204 #ifdef cimg_use_zlib
38205 cimg_snprintf(filename,
sizeof(filename),cimg_appname
"_%.4u.cimgz",snap_number++);
38207 cimg_snprintf(filename,
sizeof(filename),cimg_appname
"_%.4u.cimg",snap_number++);
38209 if ((file=std::fopen(filename,
"r"))!=0)
cimg::fclose(file);
38211 visu.draw_text(0,0,
" Saving object... ",foreground_color._data,background_color._data,1,13).display(disp);
38212 vertices.get_object3dtoCImg3d(reverse_primitives?reverse_primitives:primitives,colors,opacities).save(filename);
38213 visu.draw_text(0,0,
" Object '%s' saved. ",foreground_color._data,background_color._data,1,13,filename).display(disp);
38214 disp.set_key(key,
false); key = 0;
38216 #ifdef cimg_use_board
38217 case cimg::keyP :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
38218 static unsigned int snap_number = 0;
38219 char filename[32] = { 0 };
38222 cimg_snprintf(filename,
sizeof(filename),cimg_appname
"_%.4u.eps",snap_number++);
38223 if ((file=std::fopen(filename,
"r"))!=0)
cimg::fclose(file);
38225 visu.draw_text(0,0,
" Saving EPS snapshot... ",foreground_color._data,background_color._data,1,13).display(disp);
38226 LibBoard::Board board;
38227 (+visu)._draw_object3d(&board,zbuffer.fill(0),
38228 Xoff + visu._width/2.0f,Yoff + visu._height/2.0f,Zoff,
38229 rotated_vertices,reverse_primitives?reverse_primitives:primitives,
38230 colors,opacities,clicked?nrender_motion:nrender_static,
38231 _is_double_sided==1,focale,
38232 visu.width()/2.0f+light_x,visu.height()/2.0f+light_y,light_z,specular_lightness,specular_shininess,
38234 board.saveEPS(filename);
38235 visu.draw_text(0,0,
" Object '%s' saved. ",foreground_color._data,background_color._data,1,13,filename).display(disp);
38236 disp.set_key(key,
false); key = 0;
38238 case cimg::keyV :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
38239 static unsigned int snap_number = 0;
38240 char filename[32] = { 0 };
38243 cimg_snprintf(filename,
sizeof(filename),cimg_appname
"_%.4u.svg",snap_number++);
38244 if ((file=std::fopen(filename,
"r"))!=0)
cimg::fclose(file);
38246 visu.draw_text(0,0,
" Saving SVG snapshot... ",foreground_color._data,background_color._data,1,13).display(disp);
38247 LibBoard::Board board;
38248 (+visu)._draw_object3d(&board,zbuffer.fill(0),
38249 Xoff + visu._width/2.0f,Yoff + visu._height/2.0f,Zoff,
38250 rotated_vertices,reverse_primitives?reverse_primitives:primitives,
38251 colors,opacities,clicked?nrender_motion:nrender_static,
38252 _is_double_sided==1,focale,
38253 visu.width()/2.0f+light_x,visu.height()/2.0f+light_y,light_z,specular_lightness,specular_shininess,
38255 board.saveSVG(filename);
38256 visu.draw_text(0,0,
" Object '%s' saved. ",foreground_color._data,background_color._data,1,13,filename).display(disp);
38257 disp.set_key(key,
false); key = 0;
38261 if (disp.is_resized()) {
38262 disp.resize(
false); visu0 =
get_resize(disp,1);
38263 if (zbuffer) zbuffer.assign(disp.width(),disp.height());
38268 std::memcpy(pose_matrix,pose._data,12*
sizeof(
float));
38269 pose_matrix[12] = Xoff; pose_matrix[13] = Yoff; pose_matrix[14] = Zoff; pose_matrix[15] = sprite_scale;
38271 disp.set_button().set_key(key);
38288 const unsigned int plot_type=1,
const unsigned int vertex_type=1,
38289 const char *
const labelx=0,
const double xmin=0,
const double xmax=0,
38290 const char *
const labely=0,
const double ymin=0,
const double ymax=0)
const {
38293 "display_graph(): Empty instance.",
38296 const unsigned long siz = (
unsigned long)_width*_height*_depth, siz1 =
cimg::max(1U,siz-1);
38297 const unsigned int old_normalization = disp.
normalization();
38298 disp.
show().
flush()._normalization = 0;
38300 double y0 = ymin, y1 = ymax, nxmin = xmin, nxmax = xmax;
38301 if (nxmin==nxmax) { nxmin = 0; nxmax = siz1; }
38304 for (
bool reset_view =
true, resize_disp =
false; !key && !disp.
is_closed(); ) {
38305 if (reset_view) { x0 = 0; x1 =
width()*
height()*
depth()-1; y0 = ymin; y1 = ymax; reset_view =
false; }
38307 cimg_forC(*
this,c) zoom.get_shared_channel(c) =
CImg<T>(
data(x0,0,0,c),x1-x0+1,1,1,1,
true);
38309 if (y0==y1) { y0 = zoom.min_max(y1);
const double dy = y1 - y0; y0-=dy/20; y1+=dy/20; }
38310 if (y0==y1) { --y0; ++y1; }
38311 const CImg<intT> selection = zoom.get_select_graph(disp,plot_type,vertex_type,
38313 nxmin + x0*(nxmax-nxmin)/siz1,
38314 nxmin + x1*(nxmax-nxmin)/siz1,
38317 if (selection[0]>=0) {
38318 if (selection[2]<0) reset_view =
true;
38320 x1 = x0 + selection[2]; x0+=selection[0];
38321 if (selection[1]>=0 && selection[3]>=0) {
38322 y0 = y1 - selection[3]*(y1-y0)/(disp.
height()-32);
38323 y1-=selection[1]*(y1-y0)/(disp.
height()-32);
38327 bool go_in =
false, go_out =
false, go_left =
false, go_right =
false, go_up =
false, go_down =
false;
38328 switch (key = disp.
key()) {
38341 if (disp.
wheel()) {
38342 if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) go_out = !(go_in = disp.
wheel()>0);
38343 else if (disp.is_keySHIFTLEFT() || disp.is_keySHIFTRIGHT()) go_left = !(go_right = disp.
wheel()>0);
38344 else go_up = !(go_down = disp.
wheel()<0);
38351 mx = (mouse_x-16)*xsiz/(disp.
width()-32),
38352 cx = x0 + (mx<0?0:(mx>=xsiz?xsiz:mx));
38354 x0 = cx - 7*(cx-x0)/8; x1 = cx + 7*(x1-cx)/8;
38355 if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
38358 my = (mouse_y-16)*ysiz/(disp.
height()-32),
38359 cy = y1 - (my<0?0:(my>=ysiz?ysiz:my));
38360 y0 = cy - 7*(cy-y0)/8; y1 = cy + 7*(y1-cy)/8;
38361 }
else y0 = y1 = 0;
38365 if (x0>0 || x1<(
int)siz1) {
38366 const int delta_x = (x1-x0)/8, ndelta_x = delta_x?delta_x:(siz>1?1:0);
38367 const double ndelta_y = (y1-y0)/8;
38368 x0-=ndelta_x; x1+=ndelta_x;
38369 y0-=ndelta_y; y1+=ndelta_y;
38370 if (x0<0) { x1-=x0; x0 = 0;
if (x1>=(
int)siz) x1 = (
int)siz1; }
38371 if (x1>=(
int)siz) { x0-=(x1-siz1); x1 = (int)siz1;
if (x0<0) x0 = 0; }
38375 const int delta = (x1-x0)/5, ndelta = delta?delta:1;
38376 if (x0-ndelta>=0) { x0-=ndelta; x1-=ndelta; }
38377 else { x1-=x0; x0 = 0; }
38381 const int delta = (x1-x0)/5, ndelta = delta?delta:1;
38382 if (x1+ndelta<(
int)siz) { x0+=ndelta; x1+=ndelta; }
38383 else { x0+=(siz1-x1); x1 = siz1; }
38387 const double delta = (y1-y0)/10, ndelta = delta?delta:1;
38388 y0+=ndelta; y1+=ndelta;
38392 const double delta = (y1-y0)/10, ndelta = delta?delta:1;
38393 y0-=ndelta; y1-=ndelta;
38398 disp._normalization = old_normalization;
38404 const unsigned int plot_type=1,
const unsigned int vertex_type=1,
38405 const char *
const labelx=0,
const double xmin=0,
const double xmax=0,
38406 const char *
const labely=0,
const double ymin=0,
const double ymax=0)
const {
38409 "display_graph(): Empty instance.",
38412 return display_graph(disp.
set_title(
"%s",title),plot_type,vertex_type,labelx,xmin,xmax,labely,ymin,ymax);
38423 const CImg<T>&
save(
const char *
const filename,
const int number=-1)
const {
38426 "save(): Specified filename is (null).",
38430 char nfilename[1024] = { 0 };
38432 #ifdef cimg_save_plugin
38433 cimg_save_plugin(fn);
38435 #ifdef cimg_save_plugin1
38436 cimg_save_plugin1(fn);
38438 #ifdef cimg_save_plugin2
38439 cimg_save_plugin2(fn);
38441 #ifdef cimg_save_plugin3
38442 cimg_save_plugin3(fn);
38444 #ifdef cimg_save_plugin4
38445 cimg_save_plugin4(fn);
38447 #ifdef cimg_save_plugin5
38448 cimg_save_plugin5(fn);
38450 #ifdef cimg_save_plugin6
38451 cimg_save_plugin6(fn);
38453 #ifdef cimg_save_plugin7
38454 cimg_save_plugin7(fn);
38456 #ifdef cimg_save_plugin8
38457 cimg_save_plugin8(fn);
38532 return _save_ascii(0,filename);
38537 return _save_ascii(file,0);
38540 const CImg<T>& _save_ascii(std::FILE *
const file,
const char *
const filename)
const {
38541 if (!file && !filename)
38543 "save_ascii(): Specified filename is (null).",
38547 "save_ascii(): Empty instance, for file '%s'.",
38549 filename?filename:
"(FILE*)");
38551 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"w");
38552 std::fprintf(nfile,
"%u %u %u %u\n",_width,_height,_depth,_spectrum);
38553 const T* ptrs = _data;
38554 cimg_forYZC(*
this,y,z,c) {
38555 cimg_forX(*
this,x) std::fprintf(nfile,"%.16g ",(
double)*(ptrs++));
38556 std::fputc('\n',nfile);
38558 if (!file) cimg::fclose(nfile);
38567 return _save_cpp(0,filename);
38572 return _save_cpp(file,0);
38575 const CImg<T>& _save_cpp(std::FILE *
const file,
const char *
const filename)
const {
38576 if (!file && !filename)
38578 "save_cpp(): Specified filename is (null).",
38582 "save_cpp(): Empty instance, for file '%s'.",
38584 filename?filename:
"(FILE*)");
38586 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"w");
38587 char varname[1024] = { 0 };
38588 if (filename) std::sscanf(
cimg::basename(filename),
"%1023[a-zA-Z0-9_]",varname);
38589 if (!*varname) cimg_snprintf(varname,
sizeof(varname),
"unnamed");
38590 std::fprintf(nfile,
38591 "/* Define image '%s' of size %ux%ux%ux%u and type '%s' */\n"
38592 "%s data_%s[] = { \n ",
38594 for (
unsigned long off = 0, siz =
size()-1; off<=siz; ++off) {
38595 std::fprintf(nfile,cimg::type<T>::format(),cimg::type<T>::format((*
this)[off]));
38596 if (off==siz) std::fprintf(nfile,
" };\n");
38597 else if (!((off+1)%16)) std::fprintf(nfile,
",\n ");
38598 else std::fprintf(nfile,
", ");
38609 return _save_dlm(0,filename);
38614 return _save_dlm(file,0);
38617 const CImg<T>& _save_dlm(std::FILE *
const file,
const char *
const filename)
const {
38618 if (!file && !filename)
38620 "save_dlm(): Specified filename is (null).",
38624 "save_dlm(): Empty instance, for file '%s'.",
38626 filename?filename:
"(FILE*)");
38629 "save_dlm(): Instance is volumetric, values along Z will be unrolled in file '%s'.",
38631 filename?filename:
"(FILE*)");
38635 "save_dlm(): Instance is multispectral, values along C will be unrolled in file '%s'.",
38637 filename?filename:
"(FILE*)");
38639 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"w");
38640 const T* ptrs = _data;
38641 cimg_forYZC(*
this,y,z,c) {
38642 cimg_forX(*
this,x) std::fprintf(nfile,"%.16g%s",(
double)*(ptrs++),(x==width()-1)?"":",");
38643 std::fputc('\n',nfile);
38645 if (!file) cimg::fclose(nfile);
38654 return _save_bmp(0,filename);
38659 return _save_bmp(file,0);
38662 const CImg<T>& _save_bmp(std::FILE *
const file,
const char *
const filename)
const {
38663 if (!file && !filename)
38665 "save_bmp(): Specified filename is (null).",
38669 "save_bmp(): Empty instance, for file '%s'.",
38671 filename?filename:
"(FILE*)");
38674 "save_bmp(): Instance is volumetric, only the first slice will be saved in file '%s'.",
38676 filename?filename:
"(FILE*)");
38680 "save_bmp(): Instance is multispectral, only the three first channels will be saved in file '%s'.",
38682 filename?filename:
"(FILE*)");
38684 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"wb");
38685 unsigned char header[54] = { 0 }, align_buf[4] = { 0 };
38687 align = (4 - (3*_width)%4)%4,
38688 buf_size = (3*_width + align)*
height(),
38689 file_size = 54 + buf_size;
38690 header[0] =
'B'; header[1] =
'M';
38691 header[0x02] = file_size&0xFF;
38692 header[0x03] = (file_size>>8)&0xFF;
38693 header[0x04] = (file_size>>16)&0xFF;
38694 header[0x05] = (file_size>>24)&0xFF;
38695 header[0x0A] = 0x36;
38696 header[0x0E] = 0x28;
38697 header[0x12] = _width&0xFF;
38698 header[0x13] = (_width>>8)&0xFF;
38699 header[0x14] = (_width>>16)&0xFF;
38700 header[0x15] = (_width>>24)&0xFF;
38701 header[0x16] = _height&0xFF;
38702 header[0x17] = (_height>>8)&0xFF;
38703 header[0x18] = (_height>>16)&0xFF;
38704 header[0x19] = (_height>>24)&0xFF;
38709 header[0x22] = buf_size&0xFF;
38710 header[0x23] = (buf_size>>8)&0xFF;
38711 header[0x24] = (buf_size>>16)&0xFF;
38712 header[0x25] = (buf_size>>24)&0xFF;
38713 header[0x27] = 0x1;
38714 header[0x2B] = 0x1;
38718 *ptr_r =
data(0,_height-1,0,0),
38719 *ptr_g = (_spectrum>=2)?
data(0,_height-1,0,1):0,
38720 *ptr_b = (_spectrum>=3)?
data(0,_height-1,0,2):0;
38722 switch (_spectrum) {
38724 cimg_forY(*
this,y) {
38725 cimg_forX(*
this,x) {
38726 const unsigned char val = (
unsigned char)*(ptr_r++);
38727 std::fputc(val,nfile); std::fputc(val,nfile); std::fputc(val,nfile);
38734 cimg_forY(*
this,y) {
38735 cimg_forX(*
this,x) {
38736 std::fputc(0,nfile);
38737 std::fputc((
unsigned char)(*(ptr_g++)),nfile);
38738 std::fputc((
unsigned char)(*(ptr_r++)),nfile);
38741 ptr_r-=2*_width; ptr_g-=2*_width;
38745 cimg_forY(*
this,y) {
38746 cimg_forX(*
this,x) {
38747 std::fputc((
unsigned char)(*(ptr_b++)),nfile);
38748 std::fputc((
unsigned char)(*(ptr_g++)),nfile);
38749 std::fputc((
unsigned char)(*(ptr_r++)),nfile);
38752 ptr_r-=2*_width; ptr_g-=2*_width; ptr_b-=2*_width;
38766 return _save_jpeg(0,filename,quality);
38771 return _save_jpeg(file,0,quality);
38774 const CImg<T>& _save_jpeg(std::FILE *
const file,
const char *
const filename,
const unsigned int quality)
const {
38775 if (!file && !filename)
38777 "save_jpeg(): Specified filename is (null).",
38781 "save_jpeg(): Empty instance, for file '%s'.",
38783 filename?filename:
"(FILE*)");
38786 "save_jpeg(): Instance is volumetric, only the first slice will be saved in file '%s'.",
38788 filename?filename:
"(FILE*)");
38790 #ifndef cimg_use_jpeg
38791 if (!file)
return save_other(filename,quality);
38793 "save_jpeg(): Unable to save data in '(*FILE)' unless libjpeg is enabled.",
38796 unsigned int dimbuf = 0;
38797 J_COLOR_SPACE colortype = JCS_RGB;
38799 switch(_spectrum) {
38800 case 1 : dimbuf = 1; colortype = JCS_GRAYSCALE;
break;
38801 case 2 : dimbuf = 3; colortype = JCS_RGB;
break;
38802 case 3 : dimbuf = 3; colortype = JCS_RGB;
break;
38803 default : dimbuf = 4; colortype = JCS_CMYK;
break;
38807 struct jpeg_compress_struct cinfo;
38808 struct jpeg_error_mgr jerr;
38809 cinfo.err = jpeg_std_error(&jerr);
38810 jpeg_create_compress(&cinfo);
38811 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"wb");
38812 jpeg_stdio_dest(&cinfo,nfile);
38813 cinfo.image_width = _width;
38814 cinfo.image_height = _height;
38815 cinfo.input_components = dimbuf;
38816 cinfo.in_color_space = colortype;
38817 jpeg_set_defaults(&cinfo);
38818 jpeg_set_quality(&cinfo,quality<100?quality:100,TRUE);
38819 jpeg_start_compress(&cinfo,TRUE);
38821 JSAMPROW row_pointer[1];
38822 CImg<ucharT> buffer((
unsigned long)_width*dimbuf);
38824 while (cinfo.next_scanline < cinfo.image_height) {
38825 unsigned char *ptrd = buffer._data;
38828 switch (_spectrum) {
38830 const T *ptr_g =
data(0, cinfo.next_scanline);
38831 for(
unsigned int b = 0; b < cinfo.image_width; b++)
38832 *(ptrd++) = (
unsigned char)*(ptr_g++);
38835 const T *ptr_r =
data(0,cinfo.next_scanline,0,0),
38836 *ptr_g =
data(0,cinfo.next_scanline,0,1);
38837 for(
unsigned int b = 0; b < cinfo.image_width; ++b) {
38838 *(ptrd++) = (
unsigned char)*(ptr_r++);
38839 *(ptrd++) = (
unsigned char)*(ptr_g++);
38844 const T *ptr_r =
data(0,cinfo.next_scanline,0,0),
38845 *ptr_g =
data(0,cinfo.next_scanline,0,1),
38846 *ptr_b =
data(0,cinfo.next_scanline,0,2);
38847 for(
unsigned int b = 0; b < cinfo.image_width; ++b) {
38848 *(ptrd++) = (
unsigned char)*(ptr_r++);
38849 *(ptrd++) = (
unsigned char)*(ptr_g++);
38850 *(ptrd++) = (
unsigned char)*(ptr_b++);
38854 const T *ptr_r =
data(0,cinfo.next_scanline,0,0),
38855 *ptr_g =
data(0,cinfo.next_scanline,0,1),
38856 *ptr_b =
data(0,cinfo.next_scanline,0,2),
38857 *ptr_a =
data(0,cinfo.next_scanline,0,3);
38858 for(
unsigned int b = 0; b < cinfo.image_width; ++b) {
38859 *(ptrd++) = (
unsigned char)*(ptr_r++);
38860 *(ptrd++) = (
unsigned char)*(ptr_g++);
38861 *(ptrd++) = (
unsigned char)*(ptr_b++);
38862 *(ptrd++) = (
unsigned char)*(ptr_a++);
38866 *row_pointer = buffer._data;
38867 jpeg_write_scanlines(&cinfo,row_pointer,1);
38869 jpeg_finish_compress(&cinfo);
38871 jpeg_destroy_compress(&cinfo);
38884 "save_magick(): Specified filename is (null).",
38888 "save_magick(): Empty instance, for file '%s'.",
38891 #ifdef cimg_use_magick
38892 double stmin, stmax = (double)
max_min(stmin);
38895 "save_magick(): Instance is volumetric, only the first slice will be saved in file '%s'.",
38901 "save_magick(): Instance is multispectral, only the three first channels will be saved in file '%s'.",
38905 if (stmin<0 || (bytes_per_pixel==1 && stmax>=256) || stmax>=65536)
38907 "save_magick(): Instance has pixel values in [%g,%g], probable type overflow in file '%s'.",
38909 filename,stmin,stmax);
38911 Magick::Image image(Magick::Geometry(_width,_height),
"black");
38912 image.type(Magick::TrueColorType);
38913 image.depth(bytes_per_pixel?(8*bytes_per_pixel):(stmax>=256?16:8));
38915 *ptr_r =
data(0,0,0,0),
38916 *ptr_g = _spectrum>1?
data(0,0,0,1):0,
38917 *ptr_b = _spectrum>2?
data(0,0,0,2):0;
38918 Magick::PixelPacket *pixels = image.getPixels(0,0,_width,_height);
38919 switch (_spectrum) {
38921 for (
unsigned long off = (
unsigned long)_width*_height; off; --off) {
38922 pixels->red = pixels->green = pixels->blue = (Magick::Quantum)*(ptr_r++);
38927 for (
unsigned long off = (
unsigned long)_width*_height; off; --off) {
38928 pixels->red = (Magick::Quantum)*(ptr_r++);
38929 pixels->green = (Magick::Quantum)*(ptr_g++);
38930 pixels->blue = 0; ++pixels;
38934 for (
unsigned long off = (
unsigned long)_width*_height; off; --off) {
38935 pixels->red = (Magick::Quantum)*(ptr_r++);
38936 pixels->green = (Magick::Quantum)*(ptr_g++);
38937 pixels->blue = (Magick::Quantum)*(ptr_b++);
38941 image.syncPixels();
38942 image.write(filename);
38946 "save_magick(): Unable to save file '%s' unless libMagick++ is enabled.",
38958 const CImg<T>&
save_png(
const char *
const filename,
const unsigned int bytes_per_pixel=0)
const {
38959 return _save_png(0,filename,bytes_per_pixel);
38964 return _save_png(file,0,bytes_per_pixel);
38967 const CImg<T>& _save_png(std::FILE *
const file,
const char *
const filename,
const unsigned int bytes_per_pixel=0)
const {
38968 if (!file && !filename)
38970 "save_png(): Specified filename is (null).",
38974 "save_png(): Empty image, for file '%s'.",
38976 filename?filename:
"(FILE*)");
38977 #ifndef cimg_use_png
38981 "save_png(): Unable to save data in '(*FILE)' unless libpng is enabled.",
38984 const char *
volatile nfilename = filename;
38985 std::FILE *
volatile nfile = file?file:
cimg::fopen(nfilename,
"wb");
38987 double stmin, stmax = (double)
max_min(stmin);
38990 "save_png(): Instance is volumetric, only the first slice will be saved in file '%s'.",
38996 "save_png(): Instance is multispectral, only the three first channels will be saved in file '%s'.",
39000 if (stmin<0 || (bytes_per_pixel==1 && stmax>=256) || stmax>=65536)
39002 "save_png(): Instance has pixel values in [%g,%g], probable type overflow in file '%s'.",
39004 filename,stmin,stmax);
39007 png_voidp user_error_ptr = 0;
39008 png_error_ptr user_error_fn = 0, user_warning_fn = 0;
39009 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,user_error_ptr, user_error_fn, user_warning_fn);
39013 "save_png(): Failed to initialize 'png_ptr' structure when saving file '%s'.",
39015 nfilename?nfilename:
"(FILE*)");
39017 png_infop info_ptr = png_create_info_struct(png_ptr);
39019 png_destroy_write_struct(&png_ptr,(png_infopp)0);
39021 throw CImgIOException(_cimg_instance
39022 "save_png(): Failed to initialize 'info_ptr' structure when saving file '%s'.",
39024 nfilename?nfilename:
"(FILE*)");
39026 if (setjmp(png_jmpbuf(png_ptr))) {
39027 png_destroy_write_struct(&png_ptr, &info_ptr);
39029 throw CImgIOException(_cimg_instance
39030 "save_png(): Encountered unknown fatal error in libpng when saving file '%s'.",
39032 nfilename?nfilename:
"(FILE*)");
39034 png_init_io(png_ptr, nfile);
39035 const int bit_depth = bytes_per_pixel?(bytes_per_pixel*8):(stmax>=256?16:8);
39038 case 1 : color_type = PNG_COLOR_TYPE_GRAY;
break;
39039 case 2 : color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
break;
39040 case 3 : color_type = PNG_COLOR_TYPE_RGB;
break;
39041 default : color_type = PNG_COLOR_TYPE_RGB_ALPHA;
39043 const int interlace_type = PNG_INTERLACE_NONE;
39044 const int compression_type = PNG_COMPRESSION_TYPE_DEFAULT;
39045 const int filter_method = PNG_FILTER_TYPE_DEFAULT;
39046 png_set_IHDR(png_ptr,info_ptr,_width,_height,bit_depth,color_type,interlace_type,compression_type,filter_method);
39047 png_write_info(png_ptr,info_ptr);
39048 const int byte_depth = bit_depth>>3;
39050 const int pixel_bit_depth_flag = numChan * (bit_depth-1);
39053 png_bytep *
const imgData =
new png_byte*[_height];
39054 for (
unsigned int row = 0; row<_height; ++
row) imgData[row] =
new png_byte[byte_depth*numChan*_width];
39055 const T *pC0 =
data(0,0,0,0);
39056 switch (pixel_bit_depth_flag) {
39058 cimg_forY(*
this,y) {
39059 unsigned char *ptrd = imgData[y];
39060 cimg_forX(*
this,x) *(ptrd++) = (
unsigned char)*(pC0++);
39064 const T *pC1 =
data(0,0,0,1);
39065 cimg_forY(*
this,y) {
39066 unsigned char *ptrd = imgData[y];
39067 cimg_forX(*
this,x) {
39068 *(ptrd++) = (
unsigned char)*(pC0++);
39069 *(ptrd++) = (
unsigned char)*(pC1++);
39074 const T *pC1 =
data(0,0,0,1), *pC2 =
data(0,0,0,2);
39075 cimg_forY(*
this,y) {
39076 unsigned char *ptrd = imgData[y];
39077 cimg_forX(*
this,x) {
39078 *(ptrd++) = (
unsigned char)*(pC0++);
39079 *(ptrd++) = (
unsigned char)*(pC1++);
39080 *(ptrd++) = (
unsigned char)*(pC2++);
39085 const T *pC1 =
data(0,0,0,1), *pC2 =
data(0,0,0,2), *pC3 =
data(0,0,0,3);
39086 cimg_forY(*
this,y){
39087 unsigned char *ptrd = imgData[y];
39088 cimg_forX(*
this,x){
39089 *(ptrd++) = (
unsigned char)*(pC0++);
39090 *(ptrd++) = (
unsigned char)*(pC1++);
39091 *(ptrd++) = (
unsigned char)*(pC2++);
39092 *(ptrd++) = (
unsigned char)*(pC3++);
39097 cimg_forY(*
this,y){
39098 unsigned short *ptrd = (
unsigned short*)(imgData[y]);
39099 cimg_forX(*
this,x) *(ptrd++) = (
unsigned short)*(pC0++);
39104 const T *pC1 =
data(0,0,0,1);
39105 cimg_forY(*
this,y){
39106 unsigned short *ptrd = (
unsigned short*)(imgData[y]);
39107 cimg_forX(*
this,x) {
39108 *(ptrd++) = (
unsigned short)*(pC0++);
39109 *(ptrd++) = (
unsigned short)*(pC1++);
39115 const T *pC1 =
data(0,0,0,1), *pC2 =
data(0,0,0,2);
39116 cimg_forY(*
this,y) {
39117 unsigned short *ptrd = (
unsigned short*)(imgData[y]);
39118 cimg_forX(*
this,x) {
39119 *(ptrd++) = (
unsigned short)*(pC0++);
39120 *(ptrd++) = (
unsigned short)*(pC1++);
39121 *(ptrd++) = (
unsigned short)*(pC2++);
39127 const T *pC1 =
data(0,0,0,1), *pC2 =
data(0,0,0,2), *pC3 =
data(0,0,0,3);
39128 cimg_forY(*
this,y) {
39129 unsigned short *ptrd = (
unsigned short*)(imgData[y]);
39130 cimg_forX(*
this,x) {
39131 *(ptrd++) = (
unsigned short)*(pC0++);
39132 *(ptrd++) = (
unsigned short)*(pC1++);
39133 *(ptrd++) = (
unsigned short)*(pC2++);
39134 *(ptrd++) = (
unsigned short)*(pC3++);
39141 throw CImgIOException(_cimg_instance
39142 "save_png(): Encountered unknown fatal error in libpng when saving file '%s'.",
39144 nfilename?nfilename:
"(FILE*)");
39146 png_write_image(png_ptr,imgData);
39147 png_write_end(png_ptr,info_ptr);
39148 png_destroy_write_struct(&png_ptr, &info_ptr);
39151 cimg_forY(*
this,n) delete[] imgData[n];
39153 if (!file) cimg::fclose(nfile);
39163 const CImg<T>&
save_pnm(
const char *
const filename,
const unsigned int bytes_per_pixel=0)
const {
39164 return _save_pnm(0,filename,bytes_per_pixel);
39169 return _save_pnm(file,0,bytes_per_pixel);
39172 const CImg<T>& _save_pnm(std::FILE *
const file,
const char *
const filename,
const unsigned int bytes_per_pixel=0)
const {
39173 if (!file && !filename)
39175 "save_pnm(): Specified filename is (null).",
39179 "save_pnm(): Empty instance, for file '%s'.",
39181 filename?filename:
"(FILE*)");
39183 double stmin, stmax = (double)
max_min(stmin);
39186 "save_pnm(): Instance is volumetric, only the first slice will be saved in file '%s'.",
39188 filename?filename:
"(FILE*)");
39192 "save_pnm(): Instance is multispectral, only the three first channels will be saved in file '%s'.",
39194 filename?filename:
"(FILE*)");
39196 if (stmin<0 || (bytes_per_pixel==1 && stmax>=256) || stmax>=65536)
39198 "save_pnm(): Instance has pixel values in [%g,%g], probable type overflow in file '%s'.",
39200 stmin,stmax,filename?filename:
"(FILE*)");
39202 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"wb");
39204 *ptr_r =
data(0,0,0,0),
39205 *ptr_g = (_spectrum>=2)?
data(0,0,0,1):0,
39206 *ptr_b = (_spectrum>=3)?
data(0,0,0,2):0;
39207 const unsigned long buf_size =
cimg::min(1024*1024UL,_width*_height*(_spectrum==1?1UL:3UL));
39209 std::fprintf(nfile,
"P%c\n%u %u\n%u\n",
39210 (_spectrum==1?
'5':
'6'),_width,_height,stmax<256?255:(stmax<4096?4095:65535));
39212 switch (_spectrum) {
39214 if (bytes_per_pixel==1 || (!bytes_per_pixel && stmax<256)) {
39216 for (
long to_write = (
long)_width*_height; to_write>0; ) {
39217 const unsigned long N =
cimg::min((
unsigned long)to_write,buf_size);
39218 unsigned char *ptrd = buf._data;
39219 for (
unsigned long i = N; i>0; --i) *(ptrd++) = (
unsigned char)*(ptr_r++);
39224 CImg<ushortT> buf(buf_size);
39225 for (
long to_write = (
long)_width*_height; to_write>0; ) {
39226 const unsigned long N =
cimg::min((
unsigned long)to_write,buf_size);
39227 unsigned short *ptrd = buf._data;
39228 for (
unsigned long i = N; i>0; --i) *(ptrd++) = (
unsigned short)*(ptr_r++);
39236 if (bytes_per_pixel==1 || (!bytes_per_pixel && stmax<256)) {
39237 CImg<ucharT> buf(buf_size);
39238 for (
long to_write = (
long)_width*_height; to_write>0; ) {
39239 const unsigned long N =
cimg::min((
unsigned long)to_write,buf_size/3);
39240 unsigned char *ptrd = buf._data;
39241 for (
unsigned long i = N; i>0; --i) {
39242 *(ptrd++) = (
unsigned char)*(ptr_r++);
39243 *(ptrd++) = (
unsigned char)*(ptr_g++);
39250 CImg<ushortT> buf(buf_size);
39251 for (
long to_write = (
long)_width*_height; to_write>0; ) {
39252 const unsigned long N =
cimg::min((
unsigned long)to_write,buf_size/3);
39253 unsigned short *ptrd = buf._data;
39254 for (
unsigned long i = N; i>0; --i) {
39255 *(ptrd++) = (
unsigned short)*(ptr_r++);
39256 *(ptrd++) = (
unsigned short)*(ptr_g++);
39266 if (bytes_per_pixel==1 || (!bytes_per_pixel && stmax<256)) {
39267 CImg<ucharT> buf(buf_size);
39268 for (
long to_write = (
long)_width*_height; to_write>0; ) {
39269 const unsigned long N =
cimg::min((
unsigned long)to_write,buf_size/3);
39270 unsigned char *ptrd = buf._data;
39271 for (
unsigned long i = N; i>0; --i) {
39272 *(ptrd++) = (
unsigned char)*(ptr_r++);
39273 *(ptrd++) = (
unsigned char)*(ptr_g++);
39274 *(ptrd++) = (
unsigned char)*(ptr_b++);
39280 CImg<ushortT> buf(buf_size);
39281 for (
long to_write = (
long)_width*_height; to_write>0; ) {
39282 const unsigned long N =
cimg::min((
unsigned long)to_write,buf_size/3);
39283 unsigned short *ptrd = buf._data;
39284 for (
unsigned long i = N; i>0; --i) {
39285 *(ptrd++) = (
unsigned short)*(ptr_r++);
39286 *(ptrd++) = (
unsigned short)*(ptr_g++);
39287 *(ptrd++) = (
unsigned short)*(ptr_b++);
39305 return _save_pnk(0,filename);
39310 return _save_pnk(file,0);
39313 const CImg<T>& _save_pnk(std::FILE *
const file,
const char *
const filename)
const {
39314 if (!file && !filename)
39316 "save_pnk(): Specified filename is (null).",
39320 "save_pnk(): Empty instance, for file '%s'.",
39322 filename?filename:
"(FILE*)");
39325 "save_pnk(): Instance is multispectral, only the first channel will be saved in file '%s'.",
39327 filename?filename:
"(FILE*)");
39329 const unsigned long buf_size =
cimg::min(1024*1024LU,_width*_height*_depth);
39330 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"wb");
39331 const T *ptr =
data(0,0,0,0);
39335 std::fprintf(nfile,
"P5\n%u %u %u\n255\n",_width,_height,_depth);
39337 for (
long to_write = (
long)_width*_height*_depth; to_write>0; ) {
39338 const unsigned long N =
cimg::min((
unsigned long)to_write,buf_size);
39339 unsigned char *ptrd = buf._data;
39340 for (
unsigned long i = N; i>0; --i) *(ptrd++) = (
unsigned char)*(ptr++);
39344 }
else if (!cimg::type<T>::is_float()) {
39345 if (_depth>1) std::fprintf(nfile,
"P8\n%u %u %u\n%d\n",_width,_height,_depth,(
int)
max());
39346 else std::fprintf(nfile,
"P8\n%u %u\n%d\n",_width,_height,(
int)
max());
39347 CImg<intT> buf(buf_size);
39348 for (
long to_write = (
long)_width*_height*_depth; to_write>0; ) {
39349 const unsigned long N =
cimg::min((
unsigned long)to_write,buf_size);
39350 int *ptrd = buf._data;
39351 for (
unsigned long i = N; i>0; --i) *(ptrd++) = (int)*(ptr++);
39356 if (_depth>1) std::fprintf(nfile,
"P9\n%u %u %u\n%g\n",_width,_height,_depth,(
double)
max());
39357 else std::fprintf(nfile,
"P9\n%u %u\n%g\n",_width,_height,(
double)
max());
39358 CImg<floatT> buf(buf_size);
39359 for (
long to_write = (
long)_width*_height*_depth; to_write>0; ) {
39360 const unsigned long N =
cimg::min((
unsigned long)to_write,buf_size);
39361 float *ptrd = buf._data;
39362 for (
unsigned long i = N; i>0; --i) *(ptrd++) = (float)*(ptr++);
39377 return get_mirror(
'y')._save_pfm(0,filename);
39385 const CImg<T>& _save_pfm(std::FILE *
const file,
const char *
const filename)
const {
39386 if (!file && !filename)
39388 "save_pfm(): Specified filename is (null).",
39392 "save_pfm(): Empty instance, for file '%s'.",
39394 filename?filename:
"(FILE*)");
39397 "save_pfm(): Instance is volumetric, only the first slice will be saved in file '%s'.",
39399 filename?filename:
"(FILE*)");
39403 "save_pfm(): image instance is multispectral, only the three first channels will be saved in file '%s'.",
39405 filename?filename:
"(FILE*)");
39407 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"wb");
39409 *ptr_r =
data(0,0,0,0),
39410 *ptr_g = (_spectrum>=2)?
data(0,0,0,1):0,
39411 *ptr_b = (_spectrum>=3)?
data(0,0,0,2):0;
39412 const unsigned int buf_size =
cimg::min(1024*1024U,_width*_height*(_spectrum==1?1:3));
39414 std::fprintf(nfile,
"P%c\n%u %u\n1.0\n",
39415 (_spectrum==1?
'f':
'F'),_width,_height);
39417 switch (_spectrum) {
39420 for (
long to_write = (
long)_width*_height; to_write>0; ) {
39421 const unsigned long N =
cimg::min((
unsigned long)to_write,buf_size);
39422 float *ptrd = buf._data;
39423 for (
unsigned long i = N; i>0; --i) *(ptrd++) = (float)*(ptr_r++);
39430 CImg<floatT> buf(buf_size);
39431 for (
long to_write = (
long)_width*_height; to_write>0; ) {
39432 const unsigned int N =
cimg::min((
unsigned int)to_write,buf_size/3);
39433 float *ptrd = buf._data;
39434 for (
unsigned long i = N; i>0; --i) {
39435 *(ptrd++) = (
float)*(ptr_r++);
39436 *(ptrd++) = (
float)*(ptr_g++);
39445 CImg<floatT> buf(buf_size);
39446 for (
long to_write = (
long)_width*_height; to_write>0; ) {
39447 const unsigned int N =
cimg::min((
unsigned int)to_write,buf_size/3);
39448 float *ptrd = buf._data;
39449 for (
unsigned long i = N; i>0; --i) {
39450 *(ptrd++) = (
float)*(ptr_r++);
39451 *(ptrd++) = (
float)*(ptr_g++);
39452 *(ptrd++) = (
float)*(ptr_b++);
39469 return _save_rgb(0,filename);
39474 return _save_rgb(file,0);
39477 const CImg<T>& _save_rgb(std::FILE *
const file,
const char *
const filename)
const {
39478 if (!file && !filename)
39480 "save_rgb(): Specified filename is (null).",
39484 "save_rgb(): Empty instance, for file '%s'.",
39486 filename?filename:
"(FILE*)");
39489 "save_rgb(): image instance has not exactly 3 channels, for file '%s'.",
39491 filename?filename:
"(FILE*)");
39493 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"wb");
39494 const unsigned long wh = (
unsigned long)_width*_height;
39495 unsigned char *
const buffer =
new unsigned char[3*wh], *nbuffer = buffer;
39497 *ptr1 =
data(0,0,0,0),
39498 *ptr2 = _spectrum>1?
data(0,0,0,1):0,
39499 *ptr3 = _spectrum>2?data(0,0,0,2):0;
39500 switch (_spectrum) {
39502 for (
unsigned long k = 0; k<wh; ++k) {
39503 const unsigned char val = (
unsigned char)*(ptr1++);
39504 *(nbuffer++) = val;
39505 *(nbuffer++) = val;
39506 *(nbuffer++) = val;
39510 for (
unsigned long k = 0; k<wh; ++k) {
39511 *(nbuffer++) = (
unsigned char)(*(ptr1++));
39512 *(nbuffer++) = (
unsigned char)(*(ptr2++));
39517 for (
unsigned long k = 0; k<wh; ++k) {
39518 *(nbuffer++) = (
unsigned char)(*(ptr1++));
39519 *(nbuffer++) = (
unsigned char)(*(ptr2++));
39520 *(nbuffer++) = (
unsigned char)(*(ptr3++));
39535 return _save_rgba(0,filename);
39540 return _save_rgba(file,0);
39543 const CImg<T>& _save_rgba(std::FILE *
const file,
const char *
const filename)
const {
39544 if (!file && !filename)
39546 "save_rgba(): Specified filename is (null).",
39550 "save_rgba(): Empty instance, for file '%s'.",
39552 filename?filename:
"(FILE*)");
39555 "save_rgba(): image instance has not exactly 4 channels, for file '%s'.",
39557 filename?filename:
"(FILE*)");
39559 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"wb");
39560 const unsigned long wh = (
unsigned long)_width*_height;
39561 unsigned char *
const buffer =
new unsigned char[4*wh], *nbuffer = buffer;
39563 *ptr1 =
data(0,0,0,0),
39564 *ptr2 = _spectrum>1?
data(0,0,0,1):0,
39565 *ptr3 = _spectrum>2?data(0,0,0,2):0,
39566 *ptr4 = _spectrum>3?data(0,0,0,3):0;
39567 switch (_spectrum) {
39569 for (
unsigned long k = 0; k<wh; ++k) {
39570 const unsigned char val = (
unsigned char)*(ptr1++);
39571 *(nbuffer++) = val;
39572 *(nbuffer++) = val;
39573 *(nbuffer++) = val;
39574 *(nbuffer++) = 255;
39578 for (
unsigned long k = 0; k<wh; ++k) {
39579 *(nbuffer++) = (
unsigned char)(*(ptr1++));
39580 *(nbuffer++) = (
unsigned char)(*(ptr2++));
39582 *(nbuffer++) = 255;
39586 for (
unsigned long k = 0; k<wh; ++k) {
39587 *(nbuffer++) = (
unsigned char)(*(ptr1++));
39588 *(nbuffer++) = (
unsigned char)(*(ptr2++));
39589 *(nbuffer++) = (
unsigned char)(*(ptr3++));
39590 *(nbuffer++) = 255;
39594 for (
unsigned long k = 0; k<wh; ++k) {
39595 *(nbuffer++) = (
unsigned char)(*(ptr1++));
39596 *(nbuffer++) = (
unsigned char)(*(ptr2++));
39597 *(nbuffer++) = (
unsigned char)(*(ptr3++));
39598 *(nbuffer++) = (
unsigned char)(*(ptr4++));
39621 const CImg<T>&
save_tiff(
const char *
const filename,
const unsigned int compression_type=0)
const {
39624 "save_tiff(): Specified filename is (null).",
39628 "save_tiff(): Empty instance, for file '%s'.",
39632 #ifdef cimg_use_tiff
39633 TIFF *tif = TIFFOpen(filename,
"w");
39635 cimg_forZ(*
this,z)
get_slice(z)._save_tiff(tif,z,compression_type);
39638 "save_tiff(): Failed to open file '%s' for writing.",
39648 #ifdef cimg_use_tiff
39650 #define _cimg_save_tiff(types,typed,compression_type) \
39651 if (!std::strcmp(types,pixel_type())) { const typed foo = (typed)0; return _save_tiff(tif,directory,foo,compression_type); }
39654 template<
typename t>
39655 const CImg<T>& _save_tiff(TIFF *tif,
const unsigned int directory,
const t& pixel_t,
const unsigned int compression_type)
const {
39656 if (
is_empty() || !tif || pixel_t)
return *
this;
39657 const char *
const filename = TIFFFileName(tif);
39658 uint32 rowsperstrip = (uint32)-1;
39659 uint16 spp = _spectrum, bpp =
sizeof(t)*8, photometric;
39660 if (spp==3 || spp==4) photometric = PHOTOMETRIC_RGB;
39661 else photometric = PHOTOMETRIC_MINISBLACK;
39662 TIFFSetDirectory(tif,directory);
39663 TIFFSetField(tif,TIFFTAG_IMAGEWIDTH,_width);
39664 TIFFSetField(tif,TIFFTAG_IMAGELENGTH,_height);
39665 TIFFSetField(tif,TIFFTAG_ORIENTATION,ORIENTATION_TOPLEFT);
39666 TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,spp);
39669 else TIFFSetField(tif,TIFFTAG_SAMPLEFORMAT,2);
39670 TIFFSetField(tif,TIFFTAG_BITSPERSAMPLE,bpp);
39671 TIFFSetField(tif,TIFFTAG_PLANARCONFIG,PLANARCONFIG_CONTIG);
39672 TIFFSetField(tif,TIFFTAG_PHOTOMETRIC,photometric);
39673 TIFFSetField(tif,TIFFTAG_COMPRESSION,compression_type?(compression_type-1):COMPRESSION_NONE);
39674 rowsperstrip = TIFFDefaultStripSize(tif,rowsperstrip);
39675 TIFFSetField(tif,TIFFTAG_ROWSPERSTRIP,rowsperstrip);
39676 TIFFSetField(tif,TIFFTAG_FILLORDER,FILLORDER_MSB2LSB);
39677 TIFFSetField(tif,TIFFTAG_SOFTWARE,
"CImg");
39678 t *
const buf = (t*)_TIFFmalloc(TIFFStripSize(tif));
39680 for (
unsigned int row = 0; row<_height; row+=rowsperstrip) {
39681 uint32 nrow = (row + rowsperstrip>_height?_height-row:rowsperstrip);
39682 tstrip_t strip = TIFFComputeStrip(tif,row,0);
39684 for (
unsigned int rr = 0; rr<nrow; ++rr)
39685 for (
unsigned int cc = 0; cc<_width; ++cc)
39686 for (
unsigned int vv = 0; vv<spp; ++vv)
39687 buf[i++] = (t)(*this)(cc,row + rr,0,vv);
39688 if (TIFFWriteEncodedStrip(tif,strip,buf,i*
sizeof(t))<0)
39690 "save_tiff(): Invalid strip writing when saving file '%s'.",
39692 filename?filename:
"(FILE*)");
39696 TIFFWriteDirectory(tif);
39700 const CImg<T>& _save_tiff(TIFF *tif,
const unsigned int directory,
const unsigned int compression_type)
const {
39701 _cimg_save_tiff(
"bool",
unsigned char,compression_type);
39702 _cimg_save_tiff(
"char",
char,compression_type);
39703 _cimg_save_tiff(
"unsigned char",
unsigned char,compression_type);
39704 _cimg_save_tiff(
"short",
short,compression_type);
39705 _cimg_save_tiff(
"unsigned short",
unsigned short,compression_type);
39706 _cimg_save_tiff(
"int",
int,compression_type);
39707 _cimg_save_tiff(
"unsigned int",
unsigned int,compression_type);
39708 _cimg_save_tiff(
"long",
int,compression_type);
39709 _cimg_save_tiff(
"unsigned long",
unsigned int,compression_type);
39710 _cimg_save_tiff(
"float",
float,compression_type);
39711 _cimg_save_tiff(
"double",
float,compression_type);
39712 const char *
const filename = TIFFFileName(tif);
39713 throw CImgInstanceException(_cimg_instance
39714 "save_tiff(): Unsupported pixel type '%s' for file '%s'.",
39727 const char *
const imitate_file=0)
const {
39730 "save_minc2(): Specified filename is (null).",
39734 "save_minc2(): Empty instance, for file '%s'.",
39737 #ifndef cimg_use_minc2
39741 minc::minc_1_writer wtr;
39743 wtr.open(filename, imitate_file);
39745 minc::minc_info di;
39746 if(
width()) di.push_back(minc::dim_info(
width(),
width()*0.5, -1, minc::dim_info::DIM_X));
39747 if(
height()) di.push_back(minc::dim_info(
height(),
height()*0.5, -1, minc::dim_info::DIM_Y));
39748 if(
depth()) di.push_back(minc::dim_info(
depth(),
depth()*0.5, -1, minc::dim_info::DIM_Z));
39750 wtr.open(filename, di, 1, NC_FLOAT, 0);
39752 if(
typeid(T)==
typeid(
unsigned char))
39753 wtr.setup_write_byte();
39754 else if(
typeid(T)==
typeid(
int))
39755 wtr.setup_write_int();
39756 else if(
typeid(T)==
typeid(
double))
39757 wtr.setup_write_double();
39759 wtr.setup_write_float();
39760 minc::save_standard_volume(wtr, this->_data);
39773 "save_analyze(): Specified filename is (null).",
39777 "save_analyze(): Empty instance, for file '%s'.",
39782 char header[348] = { 0 }, hname[1024] = { 0 }, iname[1024] = { 0 };
39785 std::memset(header,0,348);
39786 if (!*ext) { cimg_snprintf(hname,
sizeof(hname),
"%s.hdr",filename); cimg_snprintf(iname,
sizeof(iname),
"%s.img",filename); }
39788 std::strcpy(hname,filename); std::strncpy(iname,filename,
sizeof(iname)-1); std::sprintf(iname + std::strlen(iname)-3,
"img");
39791 std::strcpy(hname,filename); std::strncpy(iname,filename,
sizeof(iname)-1); std::sprintf(hname + std::strlen(iname)-3,
"hdr");
39794 std::strncpy(hname,filename,
sizeof(hname)-1); *iname = 0;
39796 int *
const iheader = (
int*)header;
39798 std::strcpy(header + 4,
"CImg");
39799 std::strcpy(header + 14,
" ");
39800 ((
short*)(header + 36))[0] = 4096;
39801 ((
char*)(header + 38))[0] = 114;
39802 ((
short*)(header + 40))[0] = 4;
39803 ((
short*)(header + 40))[1] = _width;
39804 ((
short*)(header + 40))[2] = _height;
39805 ((
short*)(header + 40))[3] = _depth;
39806 ((
short*)(header + 40))[4] = _spectrum;
39820 "save_analyze(): Unsupported pixel type '%s' for file '%s'.",
39824 ((
short*)(header+70))[0] = datatype;
39825 ((
short*)(header+72))[0] =
sizeof(T);
39826 ((
float*)(header+112))[0] = 1;
39827 ((
float*)(header+76))[0] = 0;
39829 ((
float*)(header+76))[1] = voxel_size[0];
39830 ((
float*)(header+76))[2] = voxel_size[1];
39831 ((
float*)(header+76))[3] = voxel_size[2];
39832 }
else ((
float*)(header+76))[1] = ((
float*)(header+76))[2] = ((
float*)(header+76))[3] = 1;
39867 const unsigned int n0,
39868 const unsigned int x0,
const unsigned int y0,
39869 const unsigned int z0,
const unsigned int c0)
const {
39876 const unsigned int n0,
39877 const unsigned int x0,
const unsigned int y0,
39878 const unsigned int z0,
const unsigned int c0)
const {
39895 const unsigned int dx,
const unsigned int dy=1,
39896 const unsigned int dz=1,
const unsigned int dc=1) {
39906 const unsigned int dx,
const unsigned int dy=1,
39907 const unsigned int dz=1,
const unsigned int dc=1) {
39917 return _save_inr(0,filename,voxel_size);
39922 return _save_inr(file,0,voxel_size);
39925 const CImg<T>& _save_inr(std::FILE *
const file,
const char *
const filename,
const float *
const voxel_size)
const {
39926 if (!file && !filename)
39928 "save_inr(): Specified filename is (null).",
39932 "save_inr(): Empty instance, for file '%s'.",
39934 filename?filename:
"(FILE*)");
39937 const char *inrtype =
"unsigned fixed\nPIXSIZE=8 bits\nSCALE=2**0";
39938 if (!
cimg::strcasecmp(
pixel_type(),
"unsigned char")) { inrtype =
"unsigned fixed\nPIXSIZE=8 bits\nSCALE=2**0"; inrpixsize = 1; }
39940 if (!
cimg::strcasecmp(
pixel_type(),
"unsigned short")) { inrtype =
"unsigned fixed\nPIXSIZE=16 bits\nSCALE=2**0";inrpixsize = 2; }
39942 if (!
cimg::strcasecmp(
pixel_type(),
"unsigned int")) { inrtype =
"unsigned fixed\nPIXSIZE=32 bits\nSCALE=2**0";inrpixsize = 4; }
39947 throw CImgIOException(_cimg_instance
39948 "save_inr(): Unsupported pixel type '%s' for file '%s'",
39952 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"wb");
39953 char header[257] = { 0 };
39954 int err = cimg_snprintf(header,
sizeof(header),
"#INRIMAGE-4#{\nXDIM=%u\nYDIM=%u\nZDIM=%u\nVDIM=%u\n",_width,_height,_depth,_spectrum);
39955 if (voxel_size) err+=std::sprintf(header + err,
"VX=%g\nVY=%g\nVZ=%g\n",voxel_size[0],voxel_size[1],voxel_size[2]);
39956 err+=std::sprintf(header + err,
"TYPE=%s\nCPU=%s\n",inrtype,
cimg::endianness()?
"sun":
"decm");
39957 std::memset(header + err,
'\n',252 - err);
39958 std::memcpy(header + 252,
"##}\n",4);
39960 cimg_forXYZ(*
this,x,y,z) cimg_forC(*this,c) cimg::fwrite(&((*this)(x,y,z,c)),1,nfile);
39961 if (!file) cimg::fclose(nfile);
39973 "save_exr(): Specified filename is (null).",
39977 "save_exr(): Empty instance, for file '%s'.",
39982 "save_exr(): Instance is volumetric, only the first slice will be saved in file '%s'.",
39986 #ifndef cimg_use_openexr
39989 Imf::Rgba *
const ptrd0 =
new Imf::Rgba[(
unsigned long)_width*_height], *ptrd = ptrd0, rgba;
39990 switch (_spectrum) {
39992 for (
const T *ptr_r =
data(), *
const ptr_e = ptr_r + (
unsigned long)_width*_height; ptr_r<ptr_e;) {
39993 rgba.r = rgba.g = rgba.b = (half)(*(ptr_r++));
39999 for (
const T *ptr_r =
data(), *ptr_g =
data(0,0,0,1), *
const ptr_e = ptr_r + (
unsigned long)_width*_height; ptr_r<ptr_e; ) {
40000 rgba.r = (half)(*(ptr_r++));
40001 rgba.g = (half)(*(ptr_g++));
40008 for (
const T *ptr_r =
data(), *ptr_g =
data(0,0,0,1), *ptr_b =
data(0,0,0,2), *
const ptr_e = ptr_r + (
unsigned long)_width*_height; ptr_r<ptr_e;) {
40009 rgba.r = (half)(*(ptr_r++));
40010 rgba.g = (half)(*(ptr_g++));
40011 rgba.b = (half)(*(ptr_b++));
40017 for (
const T *ptr_r =
data(), *ptr_g =
data(0,0,0,1), *ptr_b =
data(0,0,0,2), *ptr_a =
data(0,0,0,3),
40018 *
const ptr_e = ptr_r + (
unsigned long)_width*_height; ptr_r<ptr_e;) {
40019 rgba.r = (half)(*(ptr_r++));
40020 rgba.g = (half)(*(ptr_g++));
40021 rgba.b = (half)(*(ptr_b++));
40022 rgba.a = (half)(*(ptr_a++));
40027 Imf::RgbaOutputFile outFile(filename,_width,_height,
40028 _spectrum==1?Imf::WRITE_Y:_spectrum==2?Imf::WRITE_YA:_spectrum==3?Imf::WRITE_RGB:Imf::WRITE_RGBA);
40029 outFile.setFrameBuffer(ptrd0,1,_width);
40030 outFile.writePixels(_height);
40043 return _save_pandore(0,filename,colorspace);
40052 return _save_pandore(file,0,colorspace);
40055 unsigned int _save_pandore_header_length(
unsigned int id,
unsigned int *dims,
const unsigned int colorspace)
const {
40056 unsigned int nbdims = 0;
40057 if (
id==2 ||
id==3 ||
id==4) { dims[0] = 1; dims[1] = _width; nbdims = 2; }
40058 if (
id==5 ||
id==6 ||
id==7) { dims[0] = 1; dims[1] = _height; dims[2] = _width; nbdims=3; }
40059 if (
id==8 ||
id==9 ||
id==10) { dims[0] = _spectrum; dims[1] = _depth; dims[2] = _height; dims[3] = _width; nbdims = 4; }
40060 if (
id==16 ||
id==17 ||
id==18) { dims[0] = 3; dims[1] = _height; dims[2] = _width; dims[3] = colorspace; nbdims = 4; }
40061 if (
id==19 ||
id==20 ||
id==21) { dims[0] = 3; dims[1] = _depth; dims[2] = _height; dims[3] = _width; dims[4] = colorspace; nbdims = 5; }
40062 if (
id==22 ||
id==23 ||
id==25) { dims[0] = _spectrum; dims[1] = _width; nbdims = 2; }
40063 if (
id==26 ||
id==27 ||
id==29) { dims[0] = _spectrum; dims[1] = _height; dims[2] = _width; nbdims=3; }
40064 if (
id==30 ||
id==31 ||
id==33) { dims[0] = _spectrum; dims[1] = _depth; dims[2] = _height; dims[3] = _width; nbdims = 4; }
40068 const CImg<T>& _save_pandore(std::FILE *
const file,
const char *
const filename,
const unsigned int colorspace)
const {
40070 #define __cimg_save_pandore_case(dtype) \
40071 dtype *buffer = new dtype[size()]; \
40072 const T *ptrs = _data; \
40073 cimg_foroff(*this,off) *(buffer++) = (dtype)(*(ptrs++)); \
40075 cimg::fwrite(buffer,size(),nfile); \
40078 #define _cimg_save_pandore_case(sy,sz,sv,stype,id) \
40079 if (!saved && (sy?(sy==_height):true) && (sz?(sz==_depth):true) && (sv?(sv==_spectrum):true) && !std::strcmp(stype,pixel_type())) { \
40080 unsigned int *iheader = (unsigned int*)(header+12); \
40081 nbdims = _save_pandore_header_length((*iheader=id),dims,colorspace); \
40082 cimg::fwrite(header,36,nfile); \
40083 if (sizeof(unsigned long)==4) { unsigned long ndims[5] = { 0 }; for (int d = 0; d<5; ++d) ndims[d] = (unsigned long)dims[d]; cimg::fwrite(ndims,nbdims,nfile); } \
40084 else if (sizeof(unsigned int)==4) { unsigned int ndims[5] = { 0 }; for (int d = 0; d<5; ++d) ndims[d] = (unsigned int)dims[d]; cimg::fwrite(ndims,nbdims,nfile); } \
40085 else if (sizeof(unsigned short)==4) { unsigned short ndims[5] = { 0 }; for (int d = 0; d<5; ++d) ndims[d] = (unsigned short)dims[d]; cimg::fwrite(ndims,nbdims,nfile); } \
40086 else throw CImgIOException(_cimg_instance \
40087 "save_pandore(): Unsupported datatype for file '%s'.",\
40089 filename?filename:"(FILE*)"); \
40090 if (id==2 || id==5 || id==8 || id==16 || id==19 || id==22 || id==26 || id==30) { \
40091 __cimg_save_pandore_case(unsigned char); \
40092 } else if (id==3 || id==6 || id==9 || id==17 || id==20 || id==23 || id==27 || id==31) { \
40093 if (sizeof(unsigned long)==4) { __cimg_save_pandore_case(unsigned long); } \
40094 else if (sizeof(unsigned int)==4) { __cimg_save_pandore_case(unsigned int); } \
40095 else if (sizeof(unsigned short)==4) { __cimg_save_pandore_case(unsigned short); } \
40096 else throw CImgIOException(_cimg_instance \
40097 "save_pandore(): Unsupported datatype for file '%s'.",\
40099 filename?filename:"(FILE*)"); \
40100 } else if (id==4 || id==7 || id==10 || id==18 || id==21 || id==25 || id==29 || id==33) { \
40101 if (sizeof(double)==4) { __cimg_save_pandore_case(double); } \
40102 else if (sizeof(float)==4) { __cimg_save_pandore_case(float); } \
40103 else throw CImgIOException(_cimg_instance \
40104 "save_pandore(): Unsupported datatype for file '%s'.",\
40106 filename?filename:"(FILE*)"); \
40111 if (!file && !filename)
40112 throw CImgArgumentException(_cimg_instance
40113 "save_pandore(): Specified filename is (null).",
40116 throw CImgInstanceException(_cimg_instance
40117 "save_pandore(): Empty instance, for file '%s'.",
40119 filename?filename:
"(FILE*)");
40121 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"wb");
40122 unsigned char header[36] = {
'P',
'A',
'N',
'D',
'O',
'R',
'E',
'0',
'4',0,0,0,
40123 0,0,0,0,
'C',
'I',
'm',
'g',0,0,0,0,0,
'N',
'o',
' ',
'd',
'a',
't',
'e',0,0,0,0 };
40124 unsigned int nbdims, dims[5] = { 0 };
40125 bool saved =
false;
40126 _cimg_save_pandore_case(1,1,1,
"unsigned char",2);
40127 _cimg_save_pandore_case(1,1,1,
"char",3);
40128 _cimg_save_pandore_case(1,1,1,
"short",3);
40129 _cimg_save_pandore_case(1,1,1,
"unsigned short",3);
40130 _cimg_save_pandore_case(1,1,1,
"unsigned int",3);
40131 _cimg_save_pandore_case(1,1,1,
"int",3);
40132 _cimg_save_pandore_case(1,1,1,
"unsigned long",4);
40133 _cimg_save_pandore_case(1,1,1,
"long",3);
40134 _cimg_save_pandore_case(1,1,1,
"float",4);
40135 _cimg_save_pandore_case(1,1,1,
"double",4);
40137 _cimg_save_pandore_case(0,1,1,
"unsigned char",5);
40138 _cimg_save_pandore_case(0,1,1,
"char",6);
40139 _cimg_save_pandore_case(0,1,1,
"short",6);
40140 _cimg_save_pandore_case(0,1,1,
"unsigned short",6);
40141 _cimg_save_pandore_case(0,1,1,
"unsigned int",6);
40142 _cimg_save_pandore_case(0,1,1,
"int",6);
40143 _cimg_save_pandore_case(0,1,1,
"unsigned long",7);
40144 _cimg_save_pandore_case(0,1,1,
"long",6);
40145 _cimg_save_pandore_case(0,1,1,
"float",7);
40146 _cimg_save_pandore_case(0,1,1,
"double",7);
40148 _cimg_save_pandore_case(0,0,1,
"unsigned char",8);
40149 _cimg_save_pandore_case(0,0,1,
"char",9);
40150 _cimg_save_pandore_case(0,0,1,
"short",9);
40151 _cimg_save_pandore_case(0,0,1,
"unsigned short",9);
40152 _cimg_save_pandore_case(0,0,1,
"unsigned int",9);
40153 _cimg_save_pandore_case(0,0,1,
"int",9);
40154 _cimg_save_pandore_case(0,0,1,
"unsigned long",10);
40155 _cimg_save_pandore_case(0,0,1,
"long",9);
40156 _cimg_save_pandore_case(0,0,1,
"float",10);
40157 _cimg_save_pandore_case(0,0,1,
"double",10);
40159 _cimg_save_pandore_case(0,1,3,
"unsigned char",16);
40160 _cimg_save_pandore_case(0,1,3,
"char",17);
40161 _cimg_save_pandore_case(0,1,3,
"short",17);
40162 _cimg_save_pandore_case(0,1,3,
"unsigned short",17);
40163 _cimg_save_pandore_case(0,1,3,
"unsigned int",17);
40164 _cimg_save_pandore_case(0,1,3,
"int",17);
40165 _cimg_save_pandore_case(0,1,3,
"unsigned long",18);
40166 _cimg_save_pandore_case(0,1,3,
"long",17);
40167 _cimg_save_pandore_case(0,1,3,
"float",18);
40168 _cimg_save_pandore_case(0,1,3,
"double",18);
40170 _cimg_save_pandore_case(0,0,3,
"unsigned char",19);
40171 _cimg_save_pandore_case(0,0,3,
"char",20);
40172 _cimg_save_pandore_case(0,0,3,
"short",20);
40173 _cimg_save_pandore_case(0,0,3,
"unsigned short",20);
40174 _cimg_save_pandore_case(0,0,3,
"unsigned int",20);
40175 _cimg_save_pandore_case(0,0,3,
"int",20);
40176 _cimg_save_pandore_case(0,0,3,
"unsigned long",21);
40177 _cimg_save_pandore_case(0,0,3,
"long",20);
40178 _cimg_save_pandore_case(0,0,3,
"float",21);
40179 _cimg_save_pandore_case(0,0,3,
"double",21);
40181 _cimg_save_pandore_case(1,1,0,
"unsigned char",22);
40182 _cimg_save_pandore_case(1,1,0,
"char",23);
40183 _cimg_save_pandore_case(1,1,0,
"short",23);
40184 _cimg_save_pandore_case(1,1,0,
"unsigned short",23);
40185 _cimg_save_pandore_case(1,1,0,
"unsigned int",23);
40186 _cimg_save_pandore_case(1,1,0,
"int",23);
40187 _cimg_save_pandore_case(1,1,0,
"unsigned long",25);
40188 _cimg_save_pandore_case(1,1,0,
"long",23);
40189 _cimg_save_pandore_case(1,1,0,
"float",25);
40190 _cimg_save_pandore_case(1,1,0,
"double",25);
40192 _cimg_save_pandore_case(0,1,0,
"unsigned char",26);
40193 _cimg_save_pandore_case(0,1,0,
"char",27);
40194 _cimg_save_pandore_case(0,1,0,
"short",27);
40195 _cimg_save_pandore_case(0,1,0,
"unsigned short",27);
40196 _cimg_save_pandore_case(0,1,0,
"unsigned int",27);
40197 _cimg_save_pandore_case(0,1,0,
"int",27);
40198 _cimg_save_pandore_case(0,1,0,
"unsigned long",29);
40199 _cimg_save_pandore_case(0,1,0,
"long",27);
40200 _cimg_save_pandore_case(0,1,0,
"float",29);
40201 _cimg_save_pandore_case(0,1,0,
"double",29);
40203 _cimg_save_pandore_case(0,0,0,
"unsigned char",30);
40204 _cimg_save_pandore_case(0,0,0,
"char",31);
40205 _cimg_save_pandore_case(0,0,0,
"short",31);
40206 _cimg_save_pandore_case(0,0,0,
"unsigned short",31);
40207 _cimg_save_pandore_case(0,0,0,
"unsigned int",31);
40208 _cimg_save_pandore_case(0,0,0,
"int",31);
40209 _cimg_save_pandore_case(0,0,0,
"unsigned long",33);
40210 _cimg_save_pandore_case(0,0,0,
"long",31);
40211 _cimg_save_pandore_case(0,0,0,
"float",33);
40212 _cimg_save_pandore_case(0,0,0,
"double",33);
40226 return _save_raw(0,filename,is_multiplexed);
40235 return _save_raw(file,0,is_multiplexed);
40238 const CImg<T>& _save_raw(std::FILE *
const file,
const char *
const filename,
const bool is_multiplexed)
const {
40239 if (!file && !filename)
40241 "save_raw(): Specified filename is (null).",
40245 "save_raw(): empty instance, for file '%s'.",
40247 filename?filename:
"(FILE*)");
40249 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"wb");
40253 cimg_forXYZ(*
this,x,y,z) {
40254 cimg_forC(*
this,c) buf[c] = (*this)(x,y,z,c);
40255 cimg::fwrite(buf._data,_spectrum,nfile);
40258 if (!file) cimg::fclose(nfile);
40273 const
CImg<T>&
save_ffmpeg(const
char *const filename, const
unsigned int fps=25, const
unsigned int bitrate=2048)
const {
40276 "save_ffmpeg(): Specified filename is (null).",
40280 "save_ffmpeg(): Empty instance, for file '%s'.",
40285 "save_ffmpeg(): Invalid specified framerate 0, for file '%s'.",
40288 #ifndef cimg_use_ffmpeg
40305 get_split(
'z').save_yuv(filename,is_rgb);
40330 template<
typename tf,
typename tc>
40332 const char *
const filename)
const {
40333 return _save_off(primitives,colors,0,filename);
40341 template<
typename tf,
typename tc>
40343 std::FILE *
const file)
const {
40344 return _save_off(primitives,colors,file,0);
40347 template<
typename tf,
typename tc>
40349 std::FILE *
const file,
const char *
const filename)
const {
40350 if (!file && !filename)
40352 "save_off(): Specified filename is (null).",
40356 "save_off(): Empty instance, for file '%s'.",
40358 filename?filename:
"(FILE*)");
40361 char error_message[1024] = { 0 };
40362 if (!
is_object3d(primitives,colors,opacities,
true,error_message))
40363 throw CImgInstanceException(_cimg_instance
40364 "save_off(): Invalid specified 3d object, for file '%s' (%s).",
40366 filename?filename:
"(FILE*)",error_message);
40368 const CImg<tc> default_color(1,3,1,1,200);
40369 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"w");
40370 unsigned int supported_primitives = 0;
40371 cimglist_for(primitives,l) if (primitives[l].size()!=5) ++supported_primitives;
40372 std::fprintf(nfile,"OFF\n%u %u %u\n",_width,supported_primitives,3*primitives._width);
40373 cimg_forX(*this,i) std::fprintf(nfile,"%f %f %f\n",(
float)((*this)(i,0)),(
float)((*this)(i,1)),(
float)((*this)(i,2)));
40374 cimglist_for(primitives,l) {
40375 const CImg<tc>& color = l<colors.
width()?colors[l]:default_color;
40376 const unsigned int psiz = primitives[l].
size(), csiz = color.size();
40377 const float r = color[0]/255.0f, g = (csiz>1?color[1]:r)/255.0f, b = (csiz>2?color[2]:g)/255.0f;
40379 case 1 : std::fprintf(nfile,
"1 %u %f %f %f\n",(
unsigned int)primitives(l,0),r,g,b);
break;
40380 case 2 : std::fprintf(nfile,
"2 %u %u %f %f %f\n",(
unsigned int)primitives(l,0),(
unsigned int)primitives(l,1),r,g,b);
break;
40381 case 3 : std::fprintf(nfile,
"3 %u %u %u %f %f %f\n",(
unsigned int)primitives(l,0),(
unsigned int)primitives(l,2),
40382 (
unsigned int)primitives(l,1),r,g,b);
break;
40383 case 4 : std::fprintf(nfile,
"4 %u %u %u %u %f %f %f\n",(
unsigned int)primitives(l,0),(
unsigned int)primitives(l,3),
40384 (
unsigned int)primitives(l,2),(
unsigned int)primitives(l,1),r,g,b);
break;
40385 case 5 : std::fprintf(nfile,
"2 %u %u %f %f %f\n",(
unsigned int)primitives(l,0),(
unsigned int)primitives(l,1),r,g,b);
break;
40387 const unsigned int xt = (
unsigned int)primitives(l,2), yt = (
unsigned int)primitives(l,3);
40388 const float rt = color.atXY(xt,yt,0)/255.0f, gt = (csiz>1?color.atXY(xt,yt,1):r)/255.0f, bt = (csiz>2?color.atXY(xt,yt,2):g)/255.0f;
40389 std::fprintf(nfile,
"2 %u %u %f %f %f\n",(
unsigned int)primitives(l,0),(
unsigned int)primitives(l,1),rt,gt,bt);
40392 const unsigned int xt = (
unsigned int)primitives(l,3), yt = (
unsigned int)primitives(l,4);
40393 const float rt = color.atXY(xt,yt,0)/255.0f, gt = (csiz>1?color.atXY(xt,yt,1):r)/255.0f, bt = (csiz>2?color.atXY(xt,yt,2):g)/255.0f;
40394 std::fprintf(nfile,
"3 %u %u %u %f %f %f\n",(
unsigned int)primitives(l,0),(
unsigned int)primitives(l,2),
40395 (
unsigned int)primitives(l,1),rt,gt,bt);
40398 const unsigned int xt = (
unsigned int)primitives(l,4), yt = (
unsigned int)primitives(l,5);
40399 const float rt = color.atXY(xt,yt,0)/255.0f, gt = (csiz>1?color.atXY(xt,yt,1):r)/255.0f, bt = (csiz>2?color.atXY(xt,yt,2):g)/255.0f;
40400 std::fprintf(nfile,
"4 %u %u %u %u %f %f %f\n",(
unsigned int)primitives(l,0),(
unsigned int)primitives(l,3),
40401 (
unsigned int)primitives(l,2),(
unsigned int)primitives(l,1),rt,gt,bt);
40421 const unsigned int fps=25,
const unsigned int bitrate=2048)
const {
40424 "save_ffmpeg_external(): Specified filename is (null).",
40428 "save_ffmpeg_external(): Empty instance, for file '%s'.",
40446 "save_gzip_external(): Specified filename is (null).",
40450 "save_gzip_external(): Empty instance, for file '%s'.",
40454 char command[1024] = { 0 }, filetmp[512] = { 0 }, body[512] = { 0 };
40461 if (*ext2) cimg_snprintf(filetmp,
sizeof(filetmp),
"%s%c%s.%s",
cimg::temporary_path(),cimg_file_separator,cimg::filenamerand(),ext2);
40462 else cimg_snprintf(filetmp,
sizeof(filetmp),
"%s%c%s.cimg",
cimg::temporary_path(),cimg_file_separator,cimg::filenamerand());
40464 if (*ext) cimg_snprintf(filetmp,
sizeof(filetmp),
"%s%c%s.%s",
cimg::temporary_path(),cimg_file_separator,cimg::filenamerand(),ext);
40465 else cimg_snprintf(filetmp,
sizeof(filetmp),
"%s%c%s.cimg",
cimg::temporary_path(),cimg_file_separator,cimg::filenamerand());
40467 if ((file=std::fopen(filetmp,
"rb"))!=0)
cimg::fclose(file);
40470 cimg_snprintf(command,
sizeof(command),
"%s -c %s > \"%s\"",
cimg::gzip_path(),filetmp,filename);
40472 file = std::fopen(filename,
"rb");
40475 "save_gzip_external(): Failed to save file '%s' with external command 'gzip'.",
40480 std::remove(filetmp);
40494 "save_graphicsmagick_external(): Specified filename is (null).",
40498 "save_graphicsmagick_external(): Empty instance, for file '%s'.",
40502 char command[1024] = { 0 }, filetmp[512] = { 0 };
40505 cimg_snprintf(filetmp,
sizeof(filetmp),
"%s%c%s.%s",
cimg::temporary_path(),cimg_file_separator,cimg::filenamerand(),_spectrum==1?
"pgm":
"ppm");
40506 if ((file=std::fopen(filetmp,
"rb"))!=0)
cimg::fclose(file);
40509 cimg_snprintf(command,
sizeof(command),
"%s convert -quality %u \"%s\" \"%s\"",
cimg::graphicsmagick_path(),quality,filetmp,filename);
40511 file = std::fopen(filename,
"rb");
40514 "save_graphicsmagick_external(): Failed to save file '%s' with external command 'gm'.",
40519 std::remove(filetmp);
40533 "save_imagemagick_external(): Specified filename is (null).",
40537 "save_imagemagick_external(): Empty instance, for file '%s'.",
40541 char command[1024] = { 0 }, filetmp[512] = { 0 };
40544 cimg_snprintf(filetmp,
sizeof(filetmp),
"%s%c%s.%s",
cimg::temporary_path(),cimg_file_separator,cimg::filenamerand(),_spectrum==1?
"pgm":
"ppm");
40545 if ((file=std::fopen(filetmp,
"rb"))!=0)
cimg::fclose(file);
40548 cimg_snprintf(command,
sizeof(command),
"%s -quality %u \"%s\" \"%s\"",
cimg::imagemagick_path(),quality,filetmp,filename);
40550 file = std::fopen(filename,
"rb");
40553 "save_imagemagick_external(): Failed to save file '%s' with external command 'convert'.",
40558 std::remove(filetmp);
40571 "save_medcon_external(): Specified filename is (null).",
40575 "save_medcon_external(): Empty instance, for file '%s'.",
40579 char command[1024] = { 0 }, filetmp[512] = { 0 }, body[512] = { 0 };
40582 cimg_snprintf(filetmp,
sizeof(filetmp),
"%s.hdr",cimg::filenamerand());
40583 if ((file=std::fopen(filetmp,
"rb"))!=0)
cimg::fclose(file);
40586 cimg_snprintf(command,
sizeof(command),
"%s -w -c dicom -o %s -f %s",
cimg::medcon_path(),filename,filetmp);
40588 std::remove(filetmp);
40590 cimg_snprintf(filetmp,
sizeof(filetmp),
"%s.img",body);
40591 std::remove(filetmp);
40593 file = std::fopen(filename,
"rb");
40595 cimg_snprintf(command,
sizeof(command),
"m000-%s",filename);
40596 file = std::fopen(command,
"rb");
40600 "save_medcon_external(): Failed to save file '%s' with external command 'medcon'.",
40606 std::rename(command,filename);
40624 "save_other(): Specified filename is (null).",
40628 "save_other(): Empty instance, for file '%s'.",
40633 bool is_saved =
true;
40648 "save_other(): Failed to save file '%s'. Format is not natively supported, and no external commands succeeded.",
40655 static CImg<T> _logo40x38() {
40656 static bool first_time =
true;
40657 static CImg<T> res(40,38,1,3);
40659 const unsigned char *ptrs = cimg::logo40x38;
40660 T *ptr1 = res.data(0,0,0,0), *ptr2 = res.data(0,0,0,1), *ptr3 = res.data(0,0,0,2);
40661 for (
unsigned long off = 0; off<(
unsigned long)res._width*res._height;) {
40662 const unsigned char n = *(ptrs++), r = *(ptrs++), g = *(ptrs++), b = *(ptrs++);
40663 for (
unsigned int l = 0; l<n; ++off, ++l) { *(ptr1++) = (T)r; *(ptr2++) = (T)g; *(ptr3++) = (T)b; }
40665 first_time =
false;
40685 template<
typename T>
40687 unsigned int _width, _allocated_width;
40725 typedef typename cimg::superset<T,bool>::type Tbool;
40726 typedef typename cimg::superset<T,unsigned char>::type Tuchar;
40727 typedef typename cimg::superset<T,char>::type Tchar;
40728 typedef typename cimg::superset<T,unsigned short>::type Tushort;
40729 typedef typename cimg::superset<T,short>::type Tshort;
40730 typedef typename cimg::superset<T,unsigned int>::type Tuint;
40731 typedef typename cimg::superset<T,int>::type Tint;
40732 typedef typename cimg::superset<T,unsigned long>::type Tulong;
40733 typedef typename cimg::superset<T,long>::type Tlong;
40734 typedef typename cimg::superset<T,float>::type Tfloat;
40735 typedef typename cimg::superset<T,double>::type Tdouble;
40736 typedef typename cimg::last<T,bool>::type boolT;
40737 typedef typename cimg::last<T,unsigned char>::type ucharT;
40738 typedef typename cimg::last<T,char>::type charT;
40739 typedef typename cimg::last<T,unsigned short>::type ushortT;
40740 typedef typename cimg::last<T,short>::type shortT;
40741 typedef typename cimg::last<T,unsigned int>::type uintT;
40742 typedef typename cimg::last<T,int>::type intT;
40743 typedef typename cimg::last<T,unsigned long>::type ulongT;
40744 typedef typename cimg::last<T,long>::type longT;
40745 typedef typename cimg::last<T,float>::type floatT;
40746 typedef typename cimg::last<T,double>::type doubleT;
40754 #ifdef cimglist_plugin
40755 #include cimglist_plugin
40757 #ifdef cimglist_plugin1
40758 #include cimglist_plugin1
40760 #ifdef cimglist_plugin2
40761 #include cimglist_plugin2
40763 #ifdef cimglist_plugin3
40764 #include cimglist_plugin3
40766 #ifdef cimglist_plugin4
40767 #include cimglist_plugin4
40769 #ifdef cimglist_plugin5
40770 #include cimglist_plugin5
40772 #ifdef cimglist_plugin6
40773 #include cimglist_plugin6
40775 #ifdef cimglist_plugin7
40776 #include cimglist_plugin7
40778 #ifdef cimglist_plugin8
40779 #include cimglist_plugin8
40808 _width(0),_allocated_width(0),_data(0) {}
40819 else { _allocated_width = 0; _data = 0; }
40831 CImgList(
const unsigned int n,
const unsigned int width,
const unsigned int height=1,
40832 const unsigned int depth=1,
const unsigned int spectrum=1):
40833 _width(0),_allocated_width(0),_data(0) {
40847 CImgList(
const unsigned int n,
const unsigned int width,
const unsigned int height,
40848 const unsigned int depth,
const unsigned int spectrum,
const T val):
40849 _width(0),_allocated_width(0),_data(0) {
40865 CImgList(
const unsigned int n,
const unsigned int width,
const unsigned int height,
40866 const unsigned int depth,
const unsigned int spectrum,
const int val0,
const int val1, ...):
40867 _width(0),_allocated_width(0),_data(0) {
40868 #define _CImgList_stdarg(t) { \
40869 assign(n,width,height,depth,spectrum); \
40870 const unsigned long siz = (unsigned long)width*height*depth*spectrum, nsiz = siz*n; \
40871 T *ptrd = _data->_data; \
40873 va_start(ap,val1); \
40874 for (unsigned long l = 0, s = 0, i = 0; i<nsiz; ++i) { \
40875 *(ptrd++) = (T)(i==0?val0:(i==1?val1:va_arg(ap,t))); \
40876 if ((++s)==siz) { ptrd = _data[++l]._data; s = 0; } \
40880 _CImgList_stdarg(
int);
40894 CImgList(
const unsigned int n,
const unsigned int width,
const unsigned int height,
40895 const unsigned int depth,
const unsigned int spectrum,
const double val0,
const double val1, ...):
40896 _width(0),_allocated_width(0),_data(0) {
40897 _CImgList_stdarg(
double);
40906 template<
typename t>
40908 _width(0),_allocated_width(0),_data(0) {
40910 cimglist_apply(*
this,assign)(img,
is_shared);
40918 template<
typename t>
40920 _width(0),_allocated_width(0),_data(0) {
40931 template<
typename t1,
typename t2>
40933 _width(0),_allocated_width(0),_data(0) {
40945 template<
typename t1,
typename t2,
typename t3>
40947 _width(0),_allocated_width(0),_data(0) {
40960 template<
typename t1,
typename t2,
typename t3,
typename t4>
40962 _width(0),_allocated_width(0),_data(0) {
40976 template<
typename t1,
typename t2,
typename t3,
typename t4,
typename t5>
40979 _width(0),_allocated_width(0),_data(0) {
40995 template<
typename t1,
typename t2,
typename t3,
typename t4,
typename t5,
typename t6>
40998 _width(0),_allocated_width(0),_data(0) {
41015 template<
typename t1,
typename t2,
typename t3,
typename t4,
typename t5,
typename t6,
typename t7>
41018 _width(0),_allocated_width(0),_data(0) {
41036 template<
typename t1,
typename t2,
typename t3,
typename t4,
typename t5,
typename t6,
typename t7,
typename t8>
41039 _width(0),_allocated_width(0),_data(0) {
41050 template<
typename t>
41053 cimglist_for(*
this,l) _data[l].assign(list[l],
false);
41059 cimglist_for(*
this,l) _data[l].assign(list[l],list[l]._is_shared);
41067 template<
typename t>
41070 cimglist_for(*
this,l) _data[l].assign(list[l],is_shared);
41077 explicit CImgList(
const char *
const filename):_width(0),_allocated_width(0),_data(0) {
41096 cimglist_for(*
this,l) res[l].assign(_data[l],
true);
41103 cimglist_for(*
this,l) res[l].assign(_data[l],
true);
41113 _width = _allocated_width = 0;
41132 if (!n)
return assign();
41133 if (_allocated_width<n || _allocated_width>(n<<2)) {
41146 const unsigned int depth=1,
const unsigned int spectrum=1) {
41157 const unsigned int depth,
const unsigned int spectrum,
const T val) {
41168 const unsigned int depth,
const unsigned int spectrum,
const int val0,
const int val1, ...) {
41169 _CImgList_stdarg(
int);
41178 const unsigned int depth,
const unsigned int spectrum,
const double val0,
const double val1, ...) {
41179 _CImgList_stdarg(
double);
41187 template<
typename t>
41190 cimglist_apply(*
this,assign)(img,
is_shared);
41198 template<
typename t>
41209 template<
typename t1,
typename t2>
41220 template<
typename t1,
typename t2,
typename t3>
41231 template<
typename t1,
typename t2,
typename t3,
typename t4>
41243 template<
typename t1,
typename t2,
typename t3,
typename t4,
typename t5>
41256 template<
typename t1,
typename t2,
typename t3,
typename t4,
typename t5,
typename t6>
41269 template<
typename t1,
typename t2,
typename t3,
typename t4,
typename t5,
typename t6,
typename t7>
41282 template<
typename t1,
typename t2,
typename t3,
typename t4,
typename t5,
typename t6,
typename t7,
typename t8>
41296 template<
typename t>
41300 cimglist_for(*
this,l) _data[l].assign(list[l],
false);
41306 if (
this==&list)
return *
this;
41308 cimglist_for(res,l) res[l].assign(list[l],
is_shared);
41309 return res.move_to(*
this);
41317 return load(filename);
41333 template<
typename t>
41335 list.assign(_width);
41336 bool is_one_shared_element =
false;
41337 cimglist_for(*
this,l) is_one_shared_element|=_data[l]._is_shared;
41338 if (is_one_shared_element) cimglist_for(*
this,l) list[l].assign(_data[l]);
41339 else cimglist_for(*
this,l) _data[l].move_to(list[l]);
41351 template<
typename t>
41354 const unsigned int npos = pos>list._width?list._width:pos;
41355 list.insert(_width,npos);
41356 bool is_one_shared_element =
false;
41357 cimglist_for(*
this,l) is_one_shared_element|=_data[l]._is_shared;
41358 if (is_one_shared_element) cimglist_for(*
this,l) list[npos+l].assign(_data[l]);
41359 else cimglist_for(*
this,l) _data[l].move_to(list[npos+l]);
41371 cimg::swap(_allocated_width,list._allocated_width);
41385 return _empty.assign();
41400 #if cimg_verbosity>=3
41403 "operator(): Invalid image request, at position [%u].",
41417 return const_cast<CImgList<T>*
>(
this)->
operator()(pos);
41429 T&
operator()(
const unsigned int pos,
const unsigned int x,
const unsigned int y=0,
41430 const unsigned int z=0,
const unsigned int c=0) {
41431 return (*
this)[pos](x,y,z,c);
41435 const T&
operator()(
const unsigned int pos,
const unsigned int x,
const unsigned int y=0,
41436 const unsigned int z=0,
const unsigned int c=0)
const {
41437 return (*
this)[pos](x,y,z,c);
41458 template<
typename t>
41468 template<
typename t>
41483 return assign(filename);
41510 template<
typename t>
41512 return insert(img);
41519 template<
typename t>
41521 return insert(list);
41566 return (
int)_width;
41595 #if cimg_verbosity>=3
41599 "data(): Invalid pointer request, at position [%u].",
41604 return _data + pos;
41607 const CImg<T> *
data(
const unsigned int l)
const {
41608 return const_cast<CImgList<T>*
>(
this)->
data(l);
41637 return _data + _width;
41642 return _data + _width;
41661 return *(_data + _width - 1);
41666 return *(_data + _width - 1);
41676 "at(): Empty instance.",
41677 cimglist_instance);
41679 return _data[pos<0?0:pos>=(int)_width?(
int)_width-1:pos];
41692 T&
atNXYZC(
const int pos,
const int x,
const int y,
const int z,
const int c,
const T out_value) {
41693 return (pos<0 || pos>=(
int)_width)?(
cimg::temporary(out_value)=out_value):_data[pos].
atXYZC(x,y,z,c,out_value);
41697 T
atNXYZC(
const int pos,
const int x,
const int y,
const int z,
const int c,
const T out_value)
const {
41698 return (pos<0 || pos>=(
int)_width)?out_value:_data[pos].atXYZC(x,y,z,c,out_value);
41710 T&
atNXYZC(
const int pos,
const int x,
const int y,
const int z,
const int c) {
41713 "atNXYZC(): Empty instance.",
41714 cimglist_instance);
41716 return _atNXYZC(pos,x,y,z,c);
41720 T
atNXYZC(
const int pos,
const int x,
const int y,
const int z,
const int c)
const {
41723 "atNXYZC(): Empty instance.",
41724 cimglist_instance);
41726 return _atNXYZC(pos,x,y,z,c);
41729 T& _atNXYZC(
const int pos,
const int x,
const int y,
const int z,
const int c) {
41730 return _data[pos<0?0:(pos>=(int)_width?(
int)_width-1:pos)].
atXYZC(x,y,z,c);
41733 T _atNXYZC(
const int pos,
const int x,
const int y,
const int z,
const int c)
const {
41734 return _data[pos<0?0:(pos>=(int)_width?(
int)_width-1:pos)].
atXYZC(x,y,z,c);
41747 T&
atNXYZ(
const int pos,
const int x,
const int y,
const int z,
const int c,
const T out_value) {
41748 return (pos<0 || pos>=(
int)_width)?(
cimg::temporary(out_value)=out_value):_data[pos].
atXYZ(x,y,z,c,out_value);
41752 T
atNXYZ(
const int pos,
const int x,
const int y,
const int z,
const int c,
const T out_value)
const {
41753 return (pos<0 || pos>=(
int)_width)?out_value:_data[pos].atXYZ(x,y,z,c,out_value);
41765 T&
atNXYZ(
const int pos,
const int x,
const int y,
const int z,
const int c=0) {
41768 "atNXYZ(): Empty instance.",
41769 cimglist_instance);
41771 return _atNXYZ(pos,x,y,z,c);
41775 T
atNXYZ(
const int pos,
const int x,
const int y,
const int z,
const int c=0)
const {
41778 "atNXYZ(): Empty instance.",
41779 cimglist_instance);
41781 return _atNXYZ(pos,x,y,z,c);
41784 T& _atNXYZ(
const int pos,
const int x,
const int y,
const int z,
const int c=0) {
41785 return _data[pos<0?0:(pos>=(int)_width?(
int)_width-1:pos)].
atXYZ(x,y,z,c);
41788 T _atNXYZ(
const int pos,
const int x,
const int y,
const int z,
const int c=0)
const {
41789 return _data[pos<0?0:(pos>=(int)_width?(
int)_width-1:pos)].
atXYZ(x,y,z,c);
41802 T&
atNXY(
const int pos,
const int x,
const int y,
const int z,
const int c,
const T out_value) {
41803 return (pos<0 || pos>=(
int)_width)?(
cimg::temporary(out_value)=out_value):_data[pos].
atXY(x,y,z,c,out_value);
41807 T
atNXY(
const int pos,
const int x,
const int y,
const int z,
const int c,
const T out_value)
const {
41808 return (pos<0 || pos>=(
int)_width)?out_value:_data[pos].atXY(x,y,z,c,out_value);
41820 T&
atNXY(
const int pos,
const int x,
const int y,
const int z=0,
const int c=0) {
41823 "atNXY(): Empty instance.",
41824 cimglist_instance);
41826 return _atNXY(pos,x,y,z,c);
41830 T
atNXY(
const int pos,
const int x,
const int y,
const int z=0,
const int c=0)
const {
41833 "atNXY(): Empty instance.",
41834 cimglist_instance);
41836 return _atNXY(pos,x,y,z,c);
41839 T& _atNXY(
const int pos,
const int x,
const int y,
const int z=0,
const int c=0) {
41840 return _data[pos<0?0:(pos>=(int)_width?(
int)_width-1:pos)].
atXY(x,y,z,c);
41843 T _atNXY(
const int pos,
const int x,
const int y,
const int z=0,
const int c=0)
const {
41844 return _data[pos<0?0:(pos>=(int)_width?(
int)_width-1:pos)].
atXY(x,y,z,c);
41857 T&
atNX(
const int pos,
const int x,
const int y,
const int z,
const int c,
const T out_value) {
41858 return (pos<0 || pos>=(
int)_width)?(
cimg::temporary(out_value)=out_value):_data[pos].
atX(x,y,z,c,out_value);
41862 T
atNX(
const int pos,
const int x,
const int y,
const int z,
const int c,
const T out_value)
const {
41863 return (pos<0 || pos>=(
int)_width)?out_value:_data[pos].atX(x,y,z,c,out_value);
41875 T&
atNX(
const int pos,
const int x,
const int y=0,
const int z=0,
const int c=0) {
41878 "atNX(): Empty instance.",
41879 cimglist_instance);
41881 return _atNX(pos,x,y,z,c);
41885 T
atNX(
const int pos,
const int x,
const int y=0,
const int z=0,
const int c=0)
const {
41888 "atNX(): Empty instance.",
41889 cimglist_instance);
41891 return _atNX(pos,x,y,z,c);
41894 T& _atNX(
const int pos,
const int x,
const int y=0,
const int z=0,
const int c=0) {
41895 return _data[pos<0?0:(pos>=(int)_width?(
int)_width-1:pos)].
atX(x,y,z,c);
41898 T _atNX(
const int pos,
const int x,
const int y=0,
const int z=0,
const int c=0)
const {
41899 return _data[pos<0?0:(pos>=(int)_width?(
int)_width-1:pos)].
atX(x,y,z,c);
41912 T&
atN(
const int pos,
const int x,
const int y,
const int z,
const int c,
const T out_value) {
41913 return (pos<0 || pos>=(
int)_width)?(
cimg::temporary(out_value)=out_value):(*
this)(pos,x,y,z,c);
41917 T
atN(
const int pos,
const int x,
const int y,
const int z,
const int c,
const T out_value)
const {
41918 return (pos<0 || pos>=(
int)_width)?out_value:(*this)(pos,x,y,z,c);
41930 T&
atN(
const int pos,
const int x=0,
const int y=0,
const int z=0,
const int c=0) {
41933 "atN(): Empty instance.",
41934 cimglist_instance);
41935 return _atN(pos,x,y,z,c);
41939 T
atN(
const int pos,
const int x=0,
const int y=0,
const int z=0,
const int c=0)
const {
41942 "atN(): Empty instance.",
41943 cimglist_instance);
41944 return _atN(pos,x,y,z,c);
41947 T& _atN(
const int pos,
const int x=0,
const int y=0,
const int z=0,
const int c=0) {
41948 return _data[pos<0?0:(pos>=(int)_width?(
int)_width-1:pos)](x,y,z,c);
41951 T _atN(
const int pos,
const int x=0,
const int y=0,
const int z=0,
const int c=0)
const {
41952 return _data[pos<0?0:(pos>=(int)_width?(
int)_width-1:pos)](x,y,z,c);
41964 for (
unsigned int l = 0; l<_width-1; ++l) {
41966 item.
back() = separator;
41969 _data[_width-1].value_string(separator,0).move_to(items);
41971 if (max_size) { res.
crop(0,max_size); res(max_size) = 0; }
41986 return (!_data || !_width);
41994 return _width==size_n;
42001 template<
typename t>
42003 return is_sameN(list._width);
42008 #define _cimglist_def_is_same1(axis) \
42009 bool is_same##axis(const unsigned int val) const { \
42010 bool res = true; for (unsigned int l = 0; l<_width && res; ++l) res = _data[l].is_same##axis(val); return res; \
42012 bool is_sameN##axis(const unsigned int n, const unsigned int val) const { \
42013 return is_sameN(n) && is_same##axis(val); \
42016 #define _cimglist_def_is_same2(axis1,axis2) \
42017 bool is_same##axis1##axis2(const unsigned int val1, const unsigned int val2) const { \
42018 bool res = true; for (unsigned int l = 0; l<_width && res; ++l) res = _data[l].is_same##axis1##axis2(val1,val2); return res; \
42020 bool is_sameN##axis1##axis2(const unsigned int n, const unsigned int val1, const unsigned int val2) const { \
42021 return is_sameN(n) && is_same##axis1##axis2(val1,val2); \
42024 #define _cimglist_def_is_same3(axis1,axis2,axis3) \
42025 bool is_same##axis1##axis2##axis3(const unsigned int val1, const unsigned int val2, const unsigned int val3) const { \
42026 bool res = true; for (unsigned int l = 0; l<_width && res; ++l) res = _data[l].is_same##axis1##axis2##axis3(val1,val2,val3); return res; \
42028 bool is_sameN##axis1##axis2##axis3(const unsigned int n, const unsigned int val1, const unsigned int val2, const unsigned int val3) const { \
42029 return is_sameN(n) && is_same##axis1##axis2##axis3(val1,val2,val3); \
42032 #define _cimglist_def_is_same(axis) \
42033 template<typename t> bool is_same##axis(const CImg<t>& img) const { \
42034 bool res = true; for (unsigned int l = 0; l<_width && res; ++l) res = _data[l].is_same##axis(img); return res; \
42036 template<typename t> bool is_same##axis(const CImgList<t>& list) const { \
42037 const unsigned int lmin = cimg::min(_width,list._width); \
42038 bool res = true; for (unsigned int l = 0; l<lmin && res; ++l) res = _data[l].is_same##axis(list[l]); return res; \
42040 template<typename t> bool is_sameN##axis(const unsigned int n, const CImg<t>& img) const { \
42041 return (is_sameN(n) && is_same##axis(img)); \
42043 template<typename t> bool is_sameN##axis(const CImgList<t>& list) const { \
42044 return (is_sameN(list) && is_same##axis(list)); \
42047 _cimglist_def_is_same(XY)
42048 _cimglist_def_is_same(XZ)
42049 _cimglist_def_is_same(XC)
42050 _cimglist_def_is_same(YZ)
42051 _cimglist_def_is_same(YC)
42052 _cimglist_def_is_same(XYZ)
42053 _cimglist_def_is_same(XYC)
42054 _cimglist_def_is_same(YZC)
42055 _cimglist_def_is_same(XYZC)
42056 _cimglist_def_is_same1(X)
42057 _cimglist_def_is_same1(Y)
42058 _cimglist_def_is_same1(Z)
42059 _cimglist_def_is_same1(C)
42060 _cimglist_def_is_same2(X,Y)
42061 _cimglist_def_is_same2(X,Z)
42062 _cimglist_def_is_same2(X,C)
42063 _cimglist_def_is_same2(Y,Z)
42064 _cimglist_def_is_same2(Y,C)
42065 _cimglist_def_is_same2(Z,C)
42066 _cimglist_def_is_same3(X,Y,Z)
42067 _cimglist_def_is_same3(X,Y,C)
42068 _cimglist_def_is_same3(X,Z,C)
42069 _cimglist_def_is_same3(Y,Z,C)
42078 bool is_sameXYZC(const
unsigned int dx, const
unsigned int dy, const
unsigned int dz, const
unsigned int dc)
const {
42080 for (
unsigned int l = 0; l<_width && res; ++l) res = _data[l].
is_sameXYZC(dx,dy,dz,dc);
42092 bool is_sameNXYZC(
const unsigned int n,
const unsigned int dx,
const unsigned int dy,
const unsigned int dz,
const unsigned int dc)
const {
42104 bool containsNXYZC(
const int n,
const int x=0,
const int y=0,
const int z=0,
const int c=0)
const {
42106 return n>=0 && n<(int)_width && x>=0 && x<_data[n].width() && y>=0 && y<_data[n].height() &&
42107 z>=0 && z<_data[n].depth() && c>=0 && c<_data[n].spectrum();
42116 return n>=0 && n<(int)_width;
42129 template<
typename t>
42130 bool contains(
const T& pixel, t& n, t& x, t&y, t& z, t& c)
const {
42132 cimglist_for(*
this,l)
if (_data[l].
contains(pixel,x,y,z,c)) { n = (t)l;
return true; }
42145 template<
typename t>
42146 bool contains(
const T& pixel, t& n, t& x, t&y, t& z)
const {
42159 template<
typename t>
42172 template<
typename t>
42184 template<
typename t>
42195 unsigned int n, x, y, z, c;
42205 template<
typename t>
42208 const CImg<T> *
const ptr = &img;
42209 cimglist_for(*
this,i)
if (_data+i==ptr) { n = (t)i;
return true; }
42235 "min(): Empty instance.",
42236 cimglist_instance);
42237 T *ptr_min = _data->_data;
42238 T min_value = *ptr_min;
42239 cimglist_for(*
this,l) {
42240 const CImg<T>& img = _data[l];
42241 cimg_for(img,ptrs,T)
if (*ptrs<min_value) min_value = *(ptr_min=ptrs);
42250 "min(): Empty instance.",
42251 cimglist_instance);
42252 const T *ptr_min = _data->_data;
42253 T min_value = *ptr_min;
42254 cimglist_for(*
this,l) {
42255 const CImg<T>& img = _data[l];
42256 cimg_for(img,ptrs,T)
if (*ptrs<min_value) min_value = *(ptr_min=ptrs);
42267 "max(): Empty instance.",
42268 cimglist_instance);
42269 T *ptr_max = _data->_data;
42270 T max_value = *ptr_max;
42271 cimglist_for(*
this,l) {
42272 const CImg<T>& img = _data[l];
42273 cimg_for(img,ptrs,T)
if (*ptrs>max_value) max_value = *(ptr_max=ptrs);
42282 "max(): Empty instance.",
42283 cimglist_instance);
42284 const T *ptr_max = _data->_data;
42285 T max_value = *ptr_max;
42286 cimglist_for(*
this,l) {
42287 const CImg<T>& img = _data[l];
42288 cimg_for(img,ptrs,T)
if (*ptrs>max_value) max_value = *(ptr_max=ptrs);
42297 template<
typename t>
42301 "min_max(): Empty instance.",
42302 cimglist_instance);
42303 T *ptr_min = _data->_data;
42304 T min_value = *ptr_min, max_value = min_value;
42305 cimglist_for(*
this,l) {
42306 const CImg<T>& img = _data[l];
42307 cimg_for(img,ptrs,T) {
42308 const T val = *ptrs;
42309 if (val<min_value) { min_value = val; ptr_min = ptrs; }
42310 if (val>max_value) max_value = val;
42313 max_val = (t)max_value;
42321 template<
typename t>
42325 "min_max(): Empty instance.",
42326 cimglist_instance);
42327 const T *ptr_min = _data->_data;
42328 T min_value = *ptr_min, max_value = min_value;
42329 cimglist_for(*
this,l) {
42330 const CImg<T>& img = _data[l];
42331 cimg_for(img,ptrs,T) {
42332 const T val = *ptrs;
42333 if (val<min_value) { min_value = val; ptr_min = ptrs; }
42334 if (val>max_value) max_value = val;
42337 max_val = (t)max_value;
42345 template<
typename t>
42349 "max_min(): Empty instance.",
42350 cimglist_instance);
42351 T *ptr_max = _data->_data;
42352 T min_value = *ptr_max, max_value = min_value;
42353 cimglist_for(*
this,l) {
42354 const CImg<T>& img = _data[l];
42355 cimg_for(img,ptrs,T) {
42356 const T val = *ptrs;
42357 if (val>max_value) { max_value = val; ptr_max = ptrs; }
42358 if (val<min_value) min_value = val;
42361 min_val = (t)min_value;
42366 template<
typename t>
42370 "max_min(): Empty instance.",
42371 cimglist_instance);
42372 const T *ptr_max = _data->_data;
42373 T min_value = *ptr_max, max_value = min_value;
42374 cimglist_for(*
this,l) {
42375 const CImg<T>& img = _data[l];
42376 cimg_for(img,ptrs,T) {
42377 const T val = *ptrs;
42378 if (val>max_value) { max_value = val; ptr_max = ptrs; }
42379 if (val<min_value) min_value = val;
42382 min_val = (t)min_value;
42399 template<
typename t>
42401 const unsigned int npos = pos==~0U?_width:pos;
42404 "insert(): Invalid insertion request of specified image (%u,%u,%u,%u,%p) at position %u.",
42406 img._width,img._height,img._depth,img._spectrum,img._data,npos);
42409 "insert(): Invalid insertion request of specified shared image CImg<%s>(%u,%u,%u,%u,%p) at position %u "
42410 "(pixel types are different).",
42412 img.pixel_type(),img._width,img._height,img._depth,img._spectrum,img._data,npos);
42414 CImg<T> *
const new_data = (++_width>_allocated_width)?
new CImg<T>[_allocated_width?(_allocated_width<<=1):(_allocated_width=16)]:0;
42420 if (npos) std::memcpy(new_data,_data,
sizeof(
CImg<T>)*npos);
42421 if (npos!=_width-1) std::memcpy(new_data+npos+1,_data+npos,
sizeof(
CImg<T>)*(_width-1-npos));
42422 std::memset(_data,0,
sizeof(
CImg<T>)*(_width-1));
42425 }
else if (npos!=_width-1) std::memmove(_data+npos+1,_data+npos,
sizeof(
CImg<T>)*(_width-1-npos));
42426 _data[npos]._width = _data[npos]._height = _data[npos]._depth = _data[npos]._spectrum = 0; _data[npos]._data = 0;
42434 const unsigned int npos = pos==~0U?_width:pos;
42437 "insert(): Invalid insertion request of specified image (%u,%u,%u,%u,%p) at position %u.",
42439 img._width,img._height,img._depth,img._spectrum,img._data,npos);
42440 CImg<T> *
const new_data = (++_width>_allocated_width)?
new CImg<T>[_allocated_width?(_allocated_width<<=1):(_allocated_width=16)]:0;
42444 _data->_width = img._width; _data->_height = img._height; _data->_depth = img._depth; _data->_spectrum = img._spectrum;
42445 _data->_is_shared =
true; _data->_data = img._data;
42446 }
else *_data = img;
42450 if (npos) std::memcpy(new_data,_data,
sizeof(
CImg<T>)*npos);
42451 if (npos!=_width-1) std::memcpy(new_data+npos+1,_data+npos,
sizeof(
CImg<T>)*(_width-1-npos));
42453 new_data[npos]._width = img._width; new_data[npos]._height = img._height; new_data[npos]._depth = img._depth;
42454 new_data[npos]._spectrum = img._spectrum; new_data[npos]._is_shared =
true; new_data[npos]._data = img._data;
42456 new_data[npos]._width = new_data[npos]._height = new_data[npos]._depth = new_data[npos]._spectrum = 0; new_data[npos]._data = 0;
42457 new_data[npos] = img;
42459 std::memset(_data,0,
sizeof(
CImg<T>)*(_width-1));
42463 if (npos!=_width-1) std::memmove(_data+npos+1,_data+npos,
sizeof(
CImg<T>)*(_width-1-npos));
42465 _data[npos]._width = img._width; _data[npos]._height = img._height; _data[npos]._depth = img._depth; _data[npos]._spectrum = img._spectrum;
42466 _data[npos]._is_shared =
true; _data[npos]._data = img._data;
42468 _data[npos]._width = _data[npos]._height = _data[npos]._depth = _data[npos]._spectrum = 0; _data[npos]._data = 0;
42477 template<
typename t>
42489 if (!n)
return *
this;
42490 const unsigned int npos = pos==~0U?_width:pos;
42491 for (
unsigned int i = 0; i<n; ++i) insert(empty,npos+i);
42497 return (+*
this).
insert(n,pos);
42507 template<
typename t>
42509 if (!n)
return *
this;
42510 const unsigned int npos = pos==~0U?_width:pos;
42512 for (
unsigned int i = 1; i<n; ++i) insert(_data[npos],npos+i,
is_shared);
42517 template<
typename t>
42528 template<
typename t>
42530 const unsigned int npos = pos==~0U?_width:pos;
42531 if ((
void*)
this!=(
void*)&list) cimglist_for(list,l) insert(list[l],npos+l,
is_shared);
42537 template<
typename t>
42549 template<
typename t>
42551 if (!n)
return *
this;
42552 const unsigned int npos = pos==~0U?_width:pos;
42553 for (
unsigned int i = 0; i<n; ++i) insert(list,npos,
is_shared);
42558 template<
typename t>
42570 npos1 = pos1<pos2?pos1:pos2,
42571 tpos2 = pos1<pos2?pos2:pos1,
42572 npos2 = tpos2<_width?tpos2:_width-1;
42575 "remove(): Invalid remove request at positions %u->%u.",
42581 "remove(): Invalid remove request at positions %u->%u.",
42585 for (
unsigned int k = npos1; k<=npos2; ++k) _data[k].
assign();
42586 const unsigned int nb = 1 + npos2 - npos1;
42587 if (!(_width-=nb))
return assign();
42588 if (_width>(_allocated_width>>2) || _allocated_width<=16) {
42589 if (npos1!=_width) std::memmove(_data+npos1,_data+npos2+1,
sizeof(
CImg<T>)*(_width - npos1));
42590 std::memset(_data + _width,0,
sizeof(
CImg<T>)*nb);
42592 _allocated_width>>=2;
42593 while (_allocated_width>16 && _width<(_allocated_width>>1)) _allocated_width>>=1;
42595 if (npos1) std::memcpy(new_data,_data,
sizeof(
CImg<T>)*npos1);
42596 if (npos1!=_width) std::memcpy(new_data+npos1,_data+npos2+1,
sizeof(
CImg<T>)*(_width-npos1));
42597 if (_width!=_allocated_width) std::memset(new_data+_width,0,
sizeof(_allocated_width - _width));
42598 std::memset(_data,0,
sizeof(
CImg<T>)*(_width+nb));
42608 return (+*
this).
remove(pos1,pos2);
42616 return remove(pos,pos);
42621 return (+*
this).
remove(pos);
42628 return remove(_width-1);
42633 return (+*
this).
remove();
42638 for (
unsigned int l = 0; l<_width/2; ++l) (*
this)[l].
swap((*
this)[_width-1-l]);
42653 return get_images(pos0,pos1).
move_to(*
this);
42658 if (pos0>pos1 || pos1>=_width)
42660 "images(): Specified sub-list indices (%u->%u) are out of bounds.",
42664 cimglist_for(res,l) res[l].assign(_data[pos0+l]);
42674 if (pos0>pos1 || pos1>=_width)
42676 "get_shared_images(): Specified sub-list indices (%u->%u) are out of bounds.",
42680 cimglist_for(res,l) res[l].assign(_data[pos0+l],
true);
42686 if (pos0>pos1 || pos1>=_width)
42688 "get_shared_images(): Specified sub-list indices (%u->%u) are out of bounds.",
42692 cimglist_for(res,l) res[l].assign(_data[pos0+l],
true);
42703 if (_width==1)
return +((*this)[0]);
42704 unsigned int dx = 0, dy = 0, dz = 0, dc = 0, pos = 0;
42708 cimglist_for(*
this,l) {
42709 const CImg<T>& img = (*this)[l];
42712 res.assign(dx,dy,dz,dc,0);
42713 if (res) cimglist_for(*
this,l) {
42714 const CImg<T>& img = (*this)[l];
42715 if (img) res.draw_image(pos,
42716 (
int)(align*(dy-img._height)),
42717 (
int)(align*(dz-img._depth)),
42718 (
int)(align*(dc-img._spectrum)),
42724 cimglist_for(*
this,l) {
42725 const CImg<T>& img = (*this)[l];
42728 res.assign(dx,dy,dz,dc,0);
42729 if (res) cimglist_for(*
this,l) {
42730 const CImg<T>& img = (*this)[l];
42731 if (img) res.draw_image((
int)(align*(dx-img._width)),
42733 (
int)(align*(dz-img._depth)),
42734 (
int)(align*(dc-img._spectrum)),
42740 cimglist_for(*
this,l) {
42741 const CImg<T>& img = (*this)[l];
42744 res.assign(dx,dy,dz,dc,0);
42745 if (res) cimglist_for(*
this,l) {
42746 const CImg<T>& img = (*this)[l];
42747 if (img) res.draw_image((
int)(align*(dx-img._width)),
42748 (
int)(align*(dy-img._height)),
42750 (
int)(align*(dc-img._spectrum)),
42756 cimglist_for(*
this,l) {
42757 const CImg<T>& img = (*this)[l];
42760 res.assign(dx,dy,dz,dc,0);
42761 if (res) cimglist_for(*
this,l) {
42762 const CImg<T>& img = (*this)[l];
42763 if (img) res.draw_image((
int)(align*(dx-img._width)),
42764 (
int)(align*(dy-img._height)),
42765 (
int)(align*(dz-img._depth)),
42768 pos+=img._spectrum;
42781 return get_split(axis,nb).move_to(*
this);
42787 cimglist_for(*
this,l) _data[l].get_split(axis,nb).move_to(res,~0U);
42795 template<
typename t>
42797 return insert(img);
42804 template<
typename t>
42806 return insert(img,0);
42813 template<
typename t>
42815 return insert(list);
42822 template<
typename t>
42824 return insert(list,0);
42831 return remove(_width-1);
42846 return remove(iter-_data);
42865 const char axis=
'x',
const float align=0)
const {
42866 return _get_select(disp,0,feature_type,axis,align,0,
false,
false,
false);
42878 const char axis=
'x',
const float align=0)
const {
42880 return _get_select(disp,title,feature_type,axis,align,0,
false,
false,
false);
42884 const char axis,
const float align,
42885 const unsigned int orig,
const bool resize_disp,
42886 const bool exit_on_rightbutton,
const bool exit_on_wheel)
const {
42889 "select(): Empty instance.",
42890 cimglist_instance);
42894 unsigned int max_width = 0, max_height = 0, sum_width = 0, sum_height = 0;
42895 cimglist_for(*
this,l) if (_data[l]) {
42896 const CImg<T>& img = _data[l];
42898 w = CImgDisplay::_fitscreen(img._width,img._height,img._depth,128,-85,
false),
42899 h = CImgDisplay::_fitscreen(img._width,img._height,img._depth,128,-85,
true);
42900 if (w>max_width) max_width = w;
42901 if (h>max_height) max_height = h;
42902 sum_width+=w; sum_height+=h;
42906 const CImg<uintT> indices0 = _indices>
'x';
42910 if (axis==
'x') disp.
assign(cimg_fitscreen(sum_width,max_height,1),title?title:0,1);
42911 else disp.
assign(cimg_fitscreen(max_width,sum_height,1),title?title:0,1);
42913 }
else if (title) disp.
set_title(
"%s",title);
42915 if (axis==
'x') disp.
resize(cimg_fitscreen(sum_width,max_height,1),
false);
42916 else disp.
resize(cimg_fitscreen(max_width,sum_height,1),
false);
42919 const unsigned int old_normalization = disp.
normalization();
42921 disp._normalization = 0;
42923 const unsigned char foreground_color[] = { 255,255,255 }, background_color[] = { 0,0,0 };
42926 CImg<ucharT> visu0, visu;
42927 CImg<uintT> indices;
42928 CImg<intT> positions(_width,4,1,1,-1);
42929 int oindice0 = -1, oindice1 = -1, indice0 = -1, indice1 = -1;
42930 bool is_clicked =
false, is_selected =
false, text_down =
false, update_display =
true;
42931 unsigned int key = 0;
42932 while (!is_selected && !disp.
is_closed() && !key) {
42936 visu0.assign(disp._width,disp._height,1,3,0); visu.assign();
42937 (indices0.get_resize(axis==
'x'?visu0._width:visu0._height,1)).
move_to(indices);
42938 unsigned int ind = 0;
42939 if (axis==
'x')
for (
unsigned int x = 0; x<visu0._width; ) {
42940 const unsigned int x0 = x;
42942 while (x<indices._width && indices[++x]==ind) {}
42945 _img2d = src._depth>1?src.get_projections2d(src._width/2,src._height/2,src._depth/2):CImg<T>(),
42946 &img2d = _img2d?_img2d:src;
42947 CImg<ucharT> res = old_normalization==1?
42948 CImg<ucharT>(img2d.get_channels(0,
cimg::min(2,img2d.spectrum()-1)).normalize(0,255)):
42949 CImg<ucharT>(img2d.get_channels(0,
cimg::min(2,img2d.spectrum()-1)));
42950 const unsigned int h = CImgDisplay::_fitscreen(res._width,res._height,1,128,-85,
true);
42951 res.resize(x - x0,
cimg::max(32U,h*disp._height/max_height),1,res._spectrum==1?3:-100);
42952 positions(ind,0) = positions(ind,2) = (int)x0;
42953 positions(ind,1) = positions(ind,3) = (int)(align*(visu0.height()-res.height()));
42954 positions(ind,2)+=res._width;
42955 positions(ind,3)+=res._height - 1;
42956 visu0.draw_image(positions(ind,0),positions(ind,1),res);
42957 }
else for (
unsigned int y = 0; y<visu0._height; ) {
42958 const unsigned int y0 = y;
42960 while (y<visu0._height && indices[++y]==ind) {}
42963 _img2d = src._depth>1?src.get_projections2d(src._width/2,src._height/2,src._depth/2):CImg<T>(),
42964 &img2d = _img2d?_img2d:src;
42965 CImg<ucharT> res = old_normalization==1?CImg<ucharT>(img2d.get_normalize(0,255)):CImg<ucharT>(img2d);
42966 if (res._spectrum>3) res.channels(0,2);
42967 const unsigned int w = CImgDisplay::_fitscreen(res._width,res._height,1,128,-85,
false);
42968 res.resize(
cimg::max(32U,w*disp._width/max_width),y - y0,1,res._spectrum==1?3:-100);
42969 positions(ind,0) = positions(ind,2) = (int)(align*(visu0.width()-res.width()));
42970 positions(ind,1) = positions(ind,3) = (int)y0;
42971 positions(ind,2)+=res._width - 1;
42972 positions(ind,3)+=res._height;
42973 visu0.draw_image(positions(ind,0),positions(ind,1),res);
42975 if (axis==
'x') --positions(ind,2);
else --positions(ind,3);
42976 update_display =
true;
42979 if (!visu || oindice0!=indice0 || oindice1!=indice1) {
42980 if (indice0>=0 && indice1>=0) {
42981 visu.assign(visu0,
false);
42983 for (
int ind = indm; ind<=indM; ++ind) if (positions(ind,0)>=0) {
42984 visu.draw_rectangle(positions(ind,0),positions(ind,1),positions(ind,2),positions(ind,3),background_color,0.2f);
42985 if ((axis==
'x' && positions(ind,2) - positions(ind,0)>=8) ||
42986 (axis!=
'x' && positions(ind,3) - positions(ind,1)>=8))
42987 visu.draw_rectangle(positions(ind,0),positions(ind,1),positions(ind,2),positions(ind,3),foreground_color,0.9f,0x55555555);
42989 const int yt = (int)text_down?visu.height()-13:0;
42990 if (is_clicked) visu.draw_text(0,yt,
" Images %u - %u, Size = %u",foreground_color,background_color,0.7f,13,
42991 orig + indm,orig + indM,indM - indm + 1);
42992 else visu.draw_text(0,yt,
" Image %u",foreground_color,background_color,0.7f,13,
42994 update_display =
true;
42995 }
else visu.assign();
42997 if (!visu) { visu.assign(visu0,
true); update_display =
true; }
42998 if (update_display) { visu.display(disp); update_display =
false; }
43006 indice = (int)indices(axis==
'x'?xm:ym);
43008 if (!is_clicked) { is_clicked =
true; oindice0 = indice0; indice0 = indice; }
43009 oindice1 = indice1; indice1 = indice;
43010 if (!feature_type) is_selected =
true;
43012 if (!is_clicked) { oindice0 = oindice1 = indice0; indice0 = indice1 = indice; }
43013 else is_selected =
true;
43017 if (!(disp.
button()&1)) { is_clicked = is_selected =
false; indice0 = indice1 = -1; }
43019 }
else indice0 = indice1 = -1;
43022 if (disp.
button()&4) { is_clicked = is_selected =
false; indice0 = indice1 = -1; }
43023 if (disp.
button()&2 && exit_on_rightbutton) { is_selected =
true; indice1 = indice0 = -1; }
43024 if (disp.
wheel() && exit_on_wheel) is_selected =
true;
43026 switch (key = disp.
key()) {
43031 case cimg::keyD :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
43033 CImgDisplay::_fitscreen(3*disp.
width()/2,3*disp.
height()/2,1,128,-100,
true),
false).
43034 _is_resized =
true;
43035 disp.
set_key(key,
false); key = 0; visu0.assign();
43037 case cimg::keyC :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
43039 disp.
set_key(key,
false); key = 0; visu0.assign();
43041 case cimg::keyR :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
43042 disp.
set_fullscreen(
false).
resize(cimg_fitscreen(axis==
'x'?sum_width:max_width,axis==
'x'?max_height:sum_height,1),
false)._is_resized =
true;
43043 disp.
set_key(key,
false); key = 0; visu0.assign();
43045 case cimg::keyF :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
43047 disp.
set_key(key,
false); key = 0; visu0.assign();
43049 case cimg::keyS :
if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
43050 static unsigned int snap_number = 0;
43051 char filename[32] = { 0 };
43054 cimg_snprintf(filename,
sizeof(filename),cimg_appname
"_%.4u.bmp",snap_number++);
43055 if ((file=std::fopen(filename,
"r"))!=0)
cimg::fclose(file);
43058 visu.draw_text(0,0,
" Saving snapshot... ",foreground_color,background_color,1,13).display(disp);
43059 visu0.save(filename);
43060 visu.draw_text(0,0,
" Snapshot '%s' saved. ",foreground_color,background_color,1,13,filename).display(disp);
43065 if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) {
43066 static unsigned int snap_number = 0;
43067 char filename[32] = { 0 };
43070 #ifdef cimg_use_zlib
43071 cimg_snprintf(filename,
sizeof(filename),cimg_appname
"_%.4u.cimgz",snap_number++);
43073 cimg_snprintf(filename,
sizeof(filename),cimg_appname
"_%.4u.cimg",snap_number++);
43075 if ((file=std::fopen(filename,
"r"))!=0)
cimg::fclose(file);
43077 visu.draw_text(0,0,
" Saving instance... ",foreground_color,background_color,1,13).display(disp);
43079 visu.draw_text(0,0,
" Instance '%s' saved. ",foreground_color,background_color,1,13,filename).display(disp);
43084 if (ym>=0 && ym<13) {
if (!text_down) { visu.assign(); text_down =
true; }}
43085 else if (ym>=visu.height()-13) {
if(text_down) { visu.assign(); text_down =
false; }}
43087 CImg<intT> res(1,2,1,1,-1);
43088 if (is_selected) {
if (feature_type) res.fill(
cimg::min(indice0,indice1),
cimg::max(indice0,indice1));
else res.fill(indice0); }
43090 disp._normalization = old_normalization;
43091 disp._is_resized = old_is_resized;
43103 "load(): Specified filename is (null).",
43104 cimglist_instance);
43107 char filename_local[1024] = { 0 };
43109 std::remove(filename_local);
43117 #ifdef cimglist_load_plugin
43118 cimglist_load_plugin(filename);
43120 #ifdef cimglist_load_plugin1
43121 cimglist_load_plugin1(filename);
43123 #ifdef cimglist_load_plugin2
43124 cimglist_load_plugin2(filename);
43126 #ifdef cimglist_load_plugin3
43127 cimglist_load_plugin3(filename);
43129 #ifdef cimglist_load_plugin4
43130 cimglist_load_plugin4(filename);
43132 #ifdef cimglist_load_plugin5
43133 cimglist_load_plugin5(filename);
43135 #ifdef cimglist_load_plugin6
43136 cimglist_load_plugin6(filename);
43138 #ifdef cimglist_load_plugin7
43139 cimglist_load_plugin7(filename);
43141 #ifdef cimglist_load_plugin8
43142 cimglist_load_plugin8(filename);
43181 "load(): Failed to open file '%s'.",
43187 _data->load(filename);
43191 "load(): Failed to recognize format of file '%s'.",
43210 return _load_cimg(0,filename);
43223 return _load_cimg(file,0);
43231 CImgList<T>& _load_cimg(std::FILE *
const file,
const char *
const filename) {
43232 #ifdef cimg_use_zlib
43233 #define _cimgz_load_cimg_case(Tss) { \
43234 Bytef *const cbuf = new Bytef[csiz]; \
43235 cimg::fread(cbuf,csiz,nfile); \
43236 raw.assign(W,H,D,C); \
43237 unsigned long destlen = (unsigned long)raw.size()*sizeof(Tss); \
43238 uncompress((Bytef*)raw._data,&destlen,cbuf,csiz); \
43240 const Tss *ptrs = raw._data; \
43241 for (unsigned long off = raw.size(); off; --off) *(ptrd++) = (T)*(ptrs++); \
43244 #define _cimgz_load_cimg_case(Tss) \
43245 throw CImgIOException(_cimglist_instance \
43246 "load_cimg(): Unable to load compressed data from file '%s' unless zlib is enabled.", \
43247 cimglist_instance, \
43248 filename?filename:"(FILE*)");
43251 #define _cimg_load_cimg_case(Ts,Tss) \
43252 if (!loaded && !cimg::strcasecmp(Ts,str_pixeltype)) { \
43253 for (unsigned int l = 0; l<N; ++l) { \
43254 j = 0; while ((i=std::fgetc(nfile))!='\n' && i>=0) tmp[j++] = (char)i; tmp[j] = 0; \
43255 W = H = D = C = 0; csiz = 0; \
43256 if ((err = std::sscanf(tmp,"%u %u %u %u #%u",&W,&H,&D,&C,&csiz))<4) \
43257 throw CImgIOException(_cimglist_instance \
43258 "load_cimg(): Invalid specified size (%u,%u,%u,%u) of image %u in file '%s'", \
43259 cimglist_instance, \
43260 W,H,D,C,l,filename?filename:("(FILE*)")); \
43263 CImg<T> &img = _data[l]; \
43264 img.assign(W,H,D,C); \
43265 T *ptrd = img._data; \
43266 if (err==5) _cimgz_load_cimg_case(Tss) \
43267 else for (long to_read = (long)img.size(); to_read>0; ) { \
43268 raw.assign(cimg::min(to_read,cimg_iobuffer)); \
43269 cimg::fread(raw._data,raw._width,nfile); \
43270 if (endian!=cimg::endianness()) cimg::invert_endianness(raw._data,raw._width); \
43271 to_read-=raw._width; \
43272 const Tss *ptrs = raw._data; \
43273 for (unsigned long off = (unsigned long)raw._width; off; --off) *(ptrd++) = (T)*(ptrs++); \
43280 if (!filename && !file)
43282 "load_cimg(): Specified filename is (null).",
43283 cimglist_instance);
43285 const int cimg_iobuffer = 12*1024*1024;
43286 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"rb");
43288 char tmp[256] = { 0 }, str_pixeltype[256] = { 0 }, str_endian[256] = { 0 };
43289 unsigned int j, err, N = 0, W, H, D, C, csiz;
43292 j = 0;
while ((i=std::fgetc(nfile))!=
'\n' && i!=EOF && j<256) tmp[j++] = (char)i; tmp[j] = 0;
43293 }
while (*tmp==
'#' && i!=EOF);
43294 err = std::sscanf(tmp,
"%u%*c%255[A-Za-z_]%*c%255[sA-Za-z_ ]",&N,str_pixeltype,str_endian);
43297 throw CImgIOException(_cimglist_instance
43298 "load_cimg(): CImg header not found in file '%s'.",
43300 filename?filename:
"(FILE*)");
43305 _cimg_load_cimg_case(
"bool",
bool);
43306 _cimg_load_cimg_case(
"unsigned_char",
unsigned char);
43307 _cimg_load_cimg_case(
"uchar",
unsigned char);
43308 _cimg_load_cimg_case(
"char",
char);
43309 _cimg_load_cimg_case(
"unsigned_short",
unsigned short);
43310 _cimg_load_cimg_case(
"ushort",
unsigned short);
43311 _cimg_load_cimg_case(
"short",
short);
43312 _cimg_load_cimg_case(
"unsigned_int",
unsigned int);
43313 _cimg_load_cimg_case(
"uint",
unsigned int);
43314 _cimg_load_cimg_case(
"int",
int);
43315 _cimg_load_cimg_case(
"unsigned_long",
unsigned long);
43316 _cimg_load_cimg_case(
"ulong",
unsigned long);
43317 _cimg_load_cimg_case(
"long",
long);
43318 _cimg_load_cimg_case(
"float",
float);
43319 _cimg_load_cimg_case(
"double",
double);
43322 throw CImgIOException(_cimglist_instance
43323 "load_cimg(): Unsupported pixel type '%s' for file '%s'.",
43325 str_pixeltype,filename?filename:
"(FILE*)");
43346 const unsigned int n0,
const unsigned int n1,
43347 const unsigned int x0,
const unsigned int y0,
const unsigned int z0,
const unsigned int c0,
43348 const unsigned int x1,
const unsigned int y1,
const unsigned int z1,
const unsigned int c1) {
43349 return _load_cimg(0,filename,n0,n1,x0,y0,z0,c0,x1,y1,z1,c1);
43354 const unsigned int n0,
const unsigned int n1,
43355 const unsigned int x0,
const unsigned int y0,
const unsigned int z0,
const unsigned int c0,
43356 const unsigned int x1,
const unsigned int y1,
const unsigned int z1,
const unsigned int c1) {
43357 return CImgList<T>().
load_cimg(filename,n0,n1,x0,y0,z0,c0,x1,y1,z1,c1);
43375 const unsigned int n0,
const unsigned int n1,
43376 const unsigned int x0,
const unsigned int y0,
const unsigned int z0,
const unsigned int c0,
43377 const unsigned int x1,
const unsigned int y1,
const unsigned int z1,
const unsigned int c1) {
43378 return _load_cimg(file,0,n0,n1,x0,y0,z0,c0,x1,y1,z1,c1);
43383 const unsigned int n0,
const unsigned int n1,
43384 const unsigned int x0,
const unsigned int y0,
const unsigned int z0,
const unsigned int c0,
43385 const unsigned int x1,
const unsigned int y1,
const unsigned int z1,
const unsigned int c1) {
43386 return CImgList<T>().
load_cimg(file,n0,n1,x0,y0,z0,c0,x1,y1,z1,c1);
43389 CImgList<T>& _load_cimg(std::FILE *
const file,
const char *
const filename,
43390 const unsigned int n0,
const unsigned int n1,
43391 const unsigned int x0,
const unsigned int y0,
const unsigned int z0,
const unsigned int c0,
43392 const unsigned int x1,
const unsigned int y1,
const unsigned int z1,
const unsigned int c1) {
43393 #define _cimg_load_cimg_case2(Ts,Tss) \
43394 if (!loaded && !cimg::strcasecmp(Ts,str_pixeltype)) { \
43395 for (unsigned int l = 0; l<=nn1; ++l) { \
43396 j = 0; while ((i=std::fgetc(nfile))!='\n' && i>=0) tmp[j++] = (char)i; tmp[j] = 0; \
43397 W = H = D = C = 0; \
43398 if (std::sscanf(tmp,"%u %u %u %u",&W,&H,&D,&C)!=4) \
43399 throw CImgIOException(_cimglist_instance \
43400 "load_cimg(): Invalid specified size (%u,%u,%u,%u) of image %u in file '%s'", \
43401 cimglist_instance, \
43402 W,H,D,C,l,filename?filename:"(FILE*)"); \
43404 if (l<n0 || x0>=W || y0>=H || z0>=D || c0>=D) std::fseek(nfile,W*H*D*C*sizeof(Tss),SEEK_CUR); \
43406 const unsigned int \
43407 nx1 = x1>=W?W-1:x1, \
43408 ny1 = y1>=H?H-1:y1, \
43409 nz1 = z1>=D?D-1:z1, \
43410 nc1 = c1>=C?C-1:c1; \
43411 CImg<Tss> raw(1 + nx1 - x0); \
43412 CImg<T> &img = _data[l - n0]; \
43413 img.assign(1 + nx1 - x0,1 + ny1 - y0,1 + nz1 - z0,1 + nc1 - c0); \
43414 T *ptrd = img._data; \
43415 const unsigned int skipvb = c0*W*H*D*sizeof(Tss); \
43416 if (skipvb) std::fseek(nfile,skipvb,SEEK_CUR); \
43417 for (unsigned int v = 1 + nc1 - c0; v; --v) { \
43418 const unsigned int skipzb = z0*W*H*sizeof(Tss); \
43419 if (skipzb) std::fseek(nfile,skipzb,SEEK_CUR); \
43420 for (unsigned int z = 1 + nz1 - z0; z; --z) { \
43421 const unsigned int skipyb = y0*W*sizeof(Tss); \
43422 if (skipyb) std::fseek(nfile,skipyb,SEEK_CUR); \
43423 for (unsigned int y = 1 + ny1 - y0; y; --y) { \
43424 const unsigned int skipxb = x0*sizeof(Tss); \
43425 if (skipxb) std::fseek(nfile,skipxb,SEEK_CUR); \
43426 cimg::fread(raw._data,raw._width,nfile); \
43427 if (endian!=cimg::endianness()) cimg::invert_endianness(raw._data,raw._width); \
43428 const Tss *ptrs = raw._data; \
43429 for (unsigned int off = raw._width; off; --off) *(ptrd++) = (T)*(ptrs++); \
43430 const unsigned int skipxe = (W-1-nx1)*sizeof(Tss); \
43431 if (skipxe) std::fseek(nfile,skipxe,SEEK_CUR); \
43433 const unsigned int skipye = (H-1-ny1)*W*sizeof(Tss); \
43434 if (skipye) std::fseek(nfile,skipye,SEEK_CUR); \
43436 const unsigned int skipze = (D-1-nz1)*W*H*sizeof(Tss); \
43437 if (skipze) std::fseek(nfile,skipze,SEEK_CUR); \
43439 const unsigned int skipve = (C-1-nc1)*W*H*D*sizeof(Tss); \
43440 if (skipve) std::fseek(nfile,skipve,SEEK_CUR); \
43447 if (!filename && !file)
43449 "load_cimg(): Specified filename is (null).",
43450 cimglist_instance);
43452 if (n1<n0 || x1<x0 || y1<y0 || z1<z0 || c1<c0)
43454 "load_cimg(): Invalid specified sub-region coordinates [%u->%u] (%u,%u,%u,%u)->(%u,%u,%u,%u) for file '%s'.",
43456 n0,n1,x0,y0,z0,c0,x1,y1,z1,filename?filename:
"(FILE*)");
43458 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"rb");
43460 char tmp[256] = { 0 }, str_pixeltype[256] = { 0 }, str_endian[256] = { 0 };
43461 unsigned int j, err, N, W, H, D, C;
43463 j = 0;
while((i=std::fgetc(nfile))!=
'\n' && i!=EOF && j<256) tmp[j++] = (char)i; tmp[j] = 0;
43464 err = std::sscanf(tmp,
"%u%*c%255[A-Za-z_]%*c%255[sA-Za-z_ ]",&N,str_pixeltype,str_endian);
43467 throw CImgIOException(_cimglist_instance
43468 "load_cimg(): CImg header not found in file '%s'.",
43470 filename?filename:
"(FILE*)");
43474 const unsigned int nn1 = n1>=N?N-1:n1;
43476 _cimg_load_cimg_case2(
"bool",
bool);
43477 _cimg_load_cimg_case2(
"unsigned_char",
unsigned char);
43478 _cimg_load_cimg_case2(
"uchar",
unsigned char);
43479 _cimg_load_cimg_case2(
"char",
char);
43480 _cimg_load_cimg_case2(
"unsigned_short",
unsigned short);
43481 _cimg_load_cimg_case2(
"ushort",
unsigned short);
43482 _cimg_load_cimg_case2(
"short",
short);
43483 _cimg_load_cimg_case2(
"unsigned_int",
unsigned int);
43484 _cimg_load_cimg_case2(
"uint",
unsigned int);
43485 _cimg_load_cimg_case2(
"int",
int);
43486 _cimg_load_cimg_case2(
"unsigned_long",
unsigned long);
43487 _cimg_load_cimg_case2(
"ulong",
unsigned long);
43488 _cimg_load_cimg_case2(
"long",
long);
43489 _cimg_load_cimg_case2(
"float",
float);
43490 _cimg_load_cimg_case2(
"double",
double);
43493 throw CImgIOException(_cimglist_instance
43494 "load_cimg(): Unsupported pixel type '%s' for file '%s'.",
43496 str_pixeltype,filename?filename:
"(FILE*)");
43509 "load_parrec(): Specified filename is (null).",
43510 cimglist_instance);
43512 char body[1024] = { 0 }, filenamepar[1024] = { 0 }, filenamerec[1024] = { 0 };
43514 if (!std::strcmp(ext,
"par")) { std::strncpy(filenamepar,filename,
sizeof(filenamepar)-1); cimg_snprintf(filenamerec,
sizeof(filenamerec),
"%s.rec",body); }
43515 if (!std::strcmp(ext,
"PAR")) { std::strncpy(filenamepar,filename,
sizeof(filenamepar)-1); cimg_snprintf(filenamerec,
sizeof(filenamerec),
"%s.REC",body); }
43516 if (!std::strcmp(ext,
"rec")) { std::strncpy(filenamerec,filename,
sizeof(filenamerec)-1); cimg_snprintf(filenamepar,
sizeof(filenamepar),
"%s.par",body); }
43517 if (!std::strcmp(ext,
"REC")) { std::strncpy(filenamerec,filename,
sizeof(filenamerec)-1); cimg_snprintf(filenamepar,
sizeof(filenamepar),
"%s.PAR",body); }
43524 char line[256] = { 0 };
43525 do { err=std::fscanf(file,
"%255[^\n]%*c",line); }
while (err!=EOF && (*line==
'#' || *line==
'.'));
43527 unsigned int sn,size_x,size_y,pixsize;
43529 err = std::fscanf(file,
"%u%*u%*u%*u%*u%*u%*u%u%*u%u%u%g%g%g%*[^\n]",&sn,&pixsize,&size_x,&size_y,&ri,&rs,&ss);
43531 CImg<floatT>::vector((
float)sn,(
float)pixsize,(
float)size_x,(
float)size_y,ri,rs,ss,0).move_to(st_slices);
43532 unsigned int i;
for (i = 0; i<st_global._width && sn<=st_global[i][2]; ++i) {}
43536 if (size_x>vec[0]) vec[0] = size_x;
43537 if (size_y>vec[1]) vec[1] = size_y;
43540 st_slices[st_slices._width-1][7] = (float)i;
43545 std::FILE *file2 =
cimg::fopen(filenamerec,
"rb");
43546 cimglist_for(st_global,l) {
43551 cimglist_for(st_slices,l) {
43554 sn = (
unsigned int)vec[0] - 1,
43555 pixsize = (
unsigned int)vec[1],
43556 size_x = (
unsigned int)vec[2],
43557 size_y = (
unsigned int)vec[3],
43558 imn = (
unsigned int)vec[7];
43559 const float ri = vec[4], rs = vec[5], ss = vec[6];
43566 cimg_forXY(img,x,y) img(x,y,sn) = (T)(( buf(x,y)*rs + ri )/(rs*ss));
43573 cimg_forXY(img,x,y) img(x,y,sn) = (T)(( buf(x,y)*rs + ri )/(rs*ss));
43580 cimg_forXY(img,x,y) img(x,y,sn) = (T)(( buf(x,y)*rs + ri )/(rs*ss));
43586 "load_parrec(): Unsupported %d-bits pixel type for file '%s'.",
43595 "load_parrec(): Failed to recognize valid PAR-REC data in file '%s'.",
43617 const unsigned int size_x,
const unsigned int size_y,
43618 const unsigned int first_frame=0,
const unsigned int last_frame=~0U,
43619 const unsigned int step_frame=1,
const bool yuv2rgb=
true) {
43620 return _load_yuv(0,filename,size_x,size_y,first_frame,last_frame,step_frame,yuv2rgb);
43625 const unsigned int size_x,
const unsigned int size_y=1,
43626 const unsigned int first_frame=0,
const unsigned int last_frame=~0U,
43627 const unsigned int step_frame=1,
const bool yuv2rgb=
true) {
43628 return CImgList<T>().
load_yuv(filename,size_x,size_y,first_frame,last_frame,step_frame,yuv2rgb);
43633 const unsigned int size_x,
const unsigned int size_y,
43634 const unsigned int first_frame=0,
const unsigned int last_frame=~0U,
43635 const unsigned int step_frame=1,
const bool yuv2rgb=
true) {
43636 return _load_yuv(file,0,size_x,size_y,first_frame,last_frame,step_frame,yuv2rgb);
43641 const unsigned int size_x,
const unsigned int size_y=1,
43642 const unsigned int first_frame=0,
const unsigned int last_frame=~0U,
43643 const unsigned int step_frame=1,
const bool yuv2rgb=
true) {
43644 return CImgList<T>().
load_yuv(file,size_x,size_y,first_frame,last_frame,step_frame,yuv2rgb);
43647 CImgList<T>& _load_yuv(std::FILE *
const file,
const char *
const filename,
43648 const unsigned int size_x,
const unsigned int size_y,
43649 const unsigned int first_frame,
const unsigned int last_frame,
43650 const unsigned int step_frame,
const bool yuv2rgb) {
43651 if (!filename && !file)
43653 "load_yuv(): Specified filename is (null).",
43654 cimglist_instance);
43655 if (size_x%2 || size_y%2)
43657 "load_yuv(): Invalid odd XY dimensions %ux%u in file '%s'.",
43659 size_x,size_y,filename?filename:
"(FILE*)");
43660 if (!size_x || !size_y)
43662 "load_yuv(): Invalid sequence size (%u,%u) in file '%s'.",
43664 size_x,size_y,filename?filename:
"(FILE*)");
43667 nfirst_frame = first_frame<last_frame?first_frame:last_frame,
43668 nlast_frame = first_frame<last_frame?last_frame:first_frame,
43669 nstep_frame = step_frame?step_frame:1;
43671 CImg<ucharT> tmp(size_x,size_y,1,3), UV(size_x/2,size_y/2,1,2);
43672 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"rb");
43673 bool stopflag =
false;
43675 if (nfirst_frame) {
43676 err = std::fseek(nfile,nfirst_frame*(size_x*size_y + size_x*size_y/2),SEEK_CUR);
43680 "load_yuv(): File '%s' doesn't contain frame number %u.",
43682 filename?filename:
"(FILE*)",nfirst_frame);
43685 unsigned int frame;
43686 for (frame = nfirst_frame; !stopflag && frame<=nlast_frame; frame+=nstep_frame) {
43689 err = (int)std::fread((
void*)(tmp._data),1,(
unsigned long)tmp._width*tmp._height,nfile);
43690 if (err!=(
int)(tmp._width*tmp._height)) {
43694 "load_yuv(): File '%s' contains incomplete data or given image dimensions (%u,%u) are incorrect.",
43696 filename?filename:
"(FILE*)",size_x,size_y);
43700 err = (int)std::fread((
void*)(UV._data),1,(
size_t)(UV.size()),nfile);
43701 if (err!=(
int)(UV.size())) {
43705 "load_yuv(): File '%s' contains incomplete data or given image dimensions (%u,%u) are incorrect.",
43707 filename?filename:
"(FILE*)",size_x,size_y);
43709 cimg_forXY(UV,x,y) {
43710 const int x2 = x*2, y2 = y*2;
43711 tmp(x2,y2,1) = tmp(x2+1,y2,1) = tmp(x2,y2+1,1) = tmp(x2+1,y2+1,1) = UV(x,y,0);
43712 tmp(x2,y2,2) = tmp(x2+1,y2,2) = tmp(x2,y2+1,2) = tmp(x2+1,y2+1,2) = UV(x,y,1);
43714 if (yuv2rgb) tmp.YCbCrtoRGB();
43716 if (nstep_frame>1) std::fseek(nfile,(nstep_frame-1)*(size_x*size_y + size_x*size_y/2),SEEK_CUR);
43720 if (stopflag && nlast_frame!=~0U && frame!=nlast_frame)
43722 "load_yuv(): Frame %d not reached since only %u frames were found in file '%s'.",
43724 nlast_frame,frame-1,filename?filename:
"(FILE*)");
43742 const unsigned int step_frame=1,
const bool pixel_format=
true,
const bool resume=
false) {
43745 "load_ffmpeg(): Specified filename is (null).",
43746 cimglist_instance);
43749 nfirst_frame = first_frame<last_frame?first_frame:last_frame,
43750 nlast_frame = first_frame<last_frame?last_frame:first_frame,
43751 nstep_frame = step_frame?step_frame:1;
43754 #ifndef cimg_use_ffmpeg
43755 if ((nfirst_frame || nlast_frame!=~0U || nstep_frame>1) || (resume && (pixel_format || !pixel_format)))
43757 "load_ffmpeg(): Unable to load sub-frames from file '%s' unless libffmpeg is enabled.",
43763 const PixelFormat ffmpeg_pixfmt = pixel_format?PIX_FMT_RGB24:PIX_FMT_GRAY8;
43764 avcodec_register_all();
43766 static AVFormatContext *format_ctx = 0;
43767 static AVCodecContext *codec_ctx = 0;
43768 static AVCodec *codec = 0;
43769 static AVFrame *avframe = avcodec_alloc_frame(), *converted_frame = avcodec_alloc_frame();
43770 static int vstream = 0;
43773 if (!format_ctx || !codec_ctx || !codec || !avframe || !converted_frame)
43775 "load_ffmpeg(): Failed to resume loading of file '%s', due to unallocated FFMPEG structures.",
43780 if (format_ctx) av_close_input_file(format_ctx);
43781 if (av_open_input_file(&format_ctx,filename,0,0,0)!=0)
43783 "load_ffmpeg(): Failed to open file '%s'.",
43787 if (!avframe || !converted_frame || av_find_stream_info(format_ctx)<0) {
43788 av_close_input_file(format_ctx); format_ctx = 0;
43791 #if cimg_verbosity>=3
43792 dump_format(format_ctx,0,0,0);
43797 if (!first_frame && !last_frame && !step_frame) {
43798 for (vstream = 0; vstream<(int)(format_ctx->nb_streams); ++vstream)
43799 if (format_ctx->streams[vstream]->codec->codec_type==CODEC_TYPE_VIDEO)
break;
43800 if (vstream==(
int)format_ctx->nb_streams)
assign();
43806 for (nb_frames = 0; av_read_frame(format_ctx,&packet)>=0; av_free_packet(&packet))
43807 if (packet.stream_index==vstream) {
43813 framew = format_ctx->streams[vstream]->codec->width,
43814 frameh = format_ctx->streams[vstream]->codec->height;
43816 num = (float)(format_ctx->streams[vstream]->r_frame_rate).num,
43817 den = (float)(format_ctx->streams[vstream]->r_frame_rate).den,
43821 (*this)[0].assign(1,4).fill((T)nb_frames,(T)framew,(T)frameh,(T)fps);
43822 (*this)[1] = (timestamps>
'y');
43824 av_close_input_file(format_ctx); format_ctx = 0;
43828 for (vstream = 0; vstream<(int)(format_ctx->nb_streams) &&
43829 format_ctx->streams[vstream]->codec->codec_type!=CODEC_TYPE_VIDEO; ) ++vstream;
43830 if (vstream==(
int)format_ctx->nb_streams) {
43831 av_close_input_file(format_ctx); format_ctx = 0;
43834 codec_ctx = format_ctx->streams[vstream]->codec;
43835 codec = avcodec_find_decoder(codec_ctx->codec_id);
43839 if (avcodec_open(codec_ctx,codec)<0) {
43845 const unsigned int numBytes = avpicture_get_size(ffmpeg_pixfmt,codec_ctx->width,codec_ctx->height);
43846 uint8_t *
const buffer =
new uint8_t[numBytes];
43847 avpicture_fill((AVPicture *)converted_frame,buffer,ffmpeg_pixfmt,codec_ctx->width,codec_ctx->height);
43848 const T foo = (T)0;
43850 for (
unsigned int frame = 0, next_frame = nfirst_frame; frame<=nlast_frame && av_read_frame(format_ctx,&packet)>=0; ) {
43851 if (packet.stream_index==(
int)vstream) {
43853 #if defined(AV_VERSION_INT)
43854 #if LIBAVCODEC_VERSION_INT<AV_VERSION_INT(52,26,0)
43855 avcodec_decode_video(codec_ctx,avframe,&decoded,packet.data, packet.size);
43857 avcodec_decode_video2(codec_ctx,avframe,&decoded,&packet);
43860 avcodec_decode_video(codec_ctx,avframe,&decoded,packet.data, packet.size);
43863 if (frame==next_frame) {
43864 SwsContext *c = sws_getContext(codec_ctx->width,codec_ctx->height,codec_ctx->pix_fmt,codec_ctx->width,
43865 codec_ctx->height,ffmpeg_pixfmt,1,0,0,0);
43866 sws_scale(c,avframe->data,avframe->linesize,0,codec_ctx->height,converted_frame->data,converted_frame->linesize);
43867 if (ffmpeg_pixfmt==PIX_FMT_RGB24) {
43868 CImg<ucharT> next_image(*converted_frame->data,3,codec_ctx->width,codec_ctx->height,1,
true);
43869 next_image._get_permute_axes(
"yzcx",foo).move_to(*
this);
43871 CImg<ucharT> next_image(*converted_frame->data,1,codec_ctx->width,codec_ctx->height,1,
true);
43872 next_image._get_permute_axes(
"yzcx",foo).move_to(*
this);
43874 next_frame+=nstep_frame;
43878 av_free_packet(&packet);
43879 if (next_frame>nlast_frame)
break;
43889 const unsigned int step_frame=1,
const bool pixel_format=
true) {
43900 "load_ffmpeg_external(): Specified filename is (null).",
43901 cimglist_instance);
43903 char command[1024] = { 0 }, filetmp[512] = { 0 }, filetmp2[512] = { 0 };
43904 std::FILE *file = 0;
43906 cimg_snprintf(filetmp,
sizeof(filetmp),
"%s%c%s",
cimg::temporary_path(),cimg_file_separator,cimg::filenamerand());
43907 cimg_snprintf(filetmp2,
sizeof(filetmp2),
"%s_000001.ppm",filetmp);
43908 if ((file=std::fopen(filetmp2,
"rb"))!=0)
cimg::fclose(file);
43910 cimg_snprintf(filetmp2,
sizeof(filetmp2),
"%s_%%6d.ppm",filetmp);
43912 cimg_snprintf(command,
sizeof(command),
"%s -i \"%s\" %s >/dev/null 2>&1",
cimg::ffmpeg_path(),filename,filetmp2);
43914 cimg_snprintf(command,
sizeof(command),
"\"%s -i \"%s\" %s\" >NUL 2>&1",
cimg::ffmpeg_path(),filename,filetmp2);
43920 unsigned int i = 1;
43921 for (
bool stopflag =
false; !stopflag; ++i) {
43922 cimg_snprintf(filetmp2,
sizeof(filetmp2),
"%s_%.6u.ppm",filetmp,i);
43924 try { img.load_pnm(filetmp2); }
43926 if (img) { img.move_to(*
this); std::remove(filetmp2); }
43931 "load_ffmpeg_external(): Failed to open file '%s' with external command 'ffmpeg'.",
43949 "load_gzip_external(): Specified filename is (null).",
43950 cimglist_instance);
43952 char command[1024] = { 0 }, filetmp[512] = { 0 }, body[512] = { 0 };
43956 std::FILE *file = 0;
43959 if (*ext2) cimg_snprintf(filetmp,
sizeof(filetmp),
"%s%c%s.%s",
cimg::temporary_path(),cimg_file_separator,cimg::filenamerand(),ext2);
43960 else cimg_snprintf(filetmp,
sizeof(filetmp),
"%s%c%s",
cimg::temporary_path(),cimg_file_separator,cimg::filenamerand());
43962 if (*ext) cimg_snprintf(filetmp,
sizeof(filetmp),
"%s%c%s.%s",
cimg::temporary_path(),cimg_file_separator,cimg::filenamerand(),ext);
43963 else cimg_snprintf(filetmp,
sizeof(filetmp),
"%s%c%s",
cimg::temporary_path(),cimg_file_separator,cimg::filenamerand());
43965 if ((file=std::fopen(filetmp,
"rb"))!=0)
cimg::fclose(file);
43967 cimg_snprintf(command,
sizeof(command),
"%s -c \"%s\" > %s",
cimg::gunzip_path(),filename,filetmp);
43969 if (!(file = std::fopen(filetmp,
"rb"))) {
43972 "load_gzip_external(): Failed to open file '%s'.",
43978 std::remove(filetmp);
43994 template<
typename tf,
typename tc>
43997 return get_load_off(filename,primitives,colors).move_to(*
this);
44001 template<
typename tf,
typename tc>
44015 const unsigned int first_frame=0,
const unsigned int last_frame=~0U,
44016 const unsigned int step_frame=1) {
44018 nfirst_frame = first_frame<last_frame?first_frame:last_frame,
44019 nstep_frame = step_frame?step_frame:1;
44020 unsigned int nlast_frame = first_frame<last_frame?last_frame:first_frame;
44021 #ifndef cimg_use_tiff
44022 if (nfirst_frame || nlast_frame!=~0U || nstep_frame!=1)
44024 "load_tiff(): Unable to load sub-images from file '%s' unless libtiff is enabled.",
44030 TIFF *tif = TIFFOpen(filename,
"r");
44032 unsigned int nb_images = 0;
44033 do ++nb_images;
while (TIFFReadDirectory(tif));
44034 if (nfirst_frame>=nb_images || (nlast_frame!=~0U && nlast_frame>=nb_images))
44036 "load_tiff(): Invalid specified frame range is [%u,%u] (step %u) since file '%s' contains %u image(s).",
44038 nfirst_frame,nlast_frame,nstep_frame,filename,nb_images);
44040 if (nfirst_frame>=nb_images)
return assign();
44041 if (nlast_frame>=nb_images) nlast_frame = nb_images-1;
44042 assign(1+(nlast_frame-nfirst_frame)/nstep_frame);
44043 TIFFSetDirectory(tif,0);
44044 #if cimg_verbosity>=3
44045 TIFFSetWarningHandler(0);
44046 TIFFSetErrorHandler(0);
44048 cimglist_for(*
this,l) _data[l]._load_tiff(tif,nfirst_frame + l*nstep_frame);
44051 "load_tiff(): Failed to open file '%s'.",
44060 const unsigned int first_frame=0,
const unsigned int last_frame=~0U,
44061 const unsigned int step_frame=1) {
44078 unsigned int msiz = 0;
44079 cimglist_for(*
this,l) msiz+=_data[l].size();
44081 const unsigned int mdisp = msiz<8*1024?0:(msiz<8*1024*1024?1:2);
44082 char _title[64] = { 0 };
44083 if (!title) cimg_snprintf(_title,
sizeof(_title),
"CImgList<%s>",
pixel_type());
44084 std::fprintf(
cimg::output(),
"%s%s%s%s: %sthis%s = %p, %ssize%s = %u/%u [%u %s], %sdata%s = (CImg<%s>*)%p",
44085 cimg::t_magenta,cimg::t_bold,title?title:_title,cimg::t_normal,
44086 cimg::t_bold,cimg::t_normal,(
void*)
this,
44087 cimg::t_bold,cimg::t_normal,_width,_allocated_width,
44088 mdisp==0?msiz:(mdisp==1?(msiz>>10):(msiz>>20)),
44089 mdisp==0?
"b":(mdisp==1?
"Kio":
"Mio"),
44091 if (_data) std::fprintf(
cimg::output(),
"..%p.\n",(
void*)((
char*)
end()-1));
44094 char tmp[16] = { 0 };
44095 cimglist_for(*
this,ll) {
44096 cimg_snprintf(tmp,
sizeof(tmp),
"[%d]",ll);
44098 _data[ll].print(tmp,display_stats);
44099 if (ll==3 && _width>8) { ll = _width-5; std::fprintf(
cimg::output(),
" ...\n"); }
44130 const char axis=
'x',
const float align=0,
44131 unsigned int *
const XYZ=0)
const {
44132 bool is_exit =
false;
44133 return _display(disp,0,display_info,axis,align,XYZ,0,
true,is_exit);
44144 const char axis=
'x',
const float align=0,
44145 unsigned int *
const XYZ=0)
const {
44147 bool is_exit =
false;
44148 return _display(disp,title,display_info,axis,align,XYZ,0,
true,is_exit);
44152 const char axis,
const float align,
unsigned int *
const XYZ,
44153 const unsigned int orig,
const bool is_first_call,
bool &is_exit)
const {
44156 "display(): Empty instance.",
44157 cimglist_instance);
44160 unsigned int sum_width = 0, max_height = 0;
44161 cimglist_for(*
this,l) {
44162 const CImg<T> &img = _data[l];
44164 w = CImgDisplay::_fitscreen(img._width,img._height,img._depth,128,-85,
false),
44165 h = CImgDisplay::_fitscreen(img._width,img._height,img._depth,128,-85,
true);
44167 if (h>max_height) max_height = h;
44169 disp.
assign(cimg_fitscreen(sum_width,max_height,1),title?title:0,1);
44171 unsigned int max_width = 0, sum_height = 0;
44172 cimglist_for(*
this,l) {
44173 const CImg<T> &img = _data[l];
44175 w = CImgDisplay::_fitscreen(img._width,img._height,img._depth,128,-85,
false),
44176 h = CImgDisplay::_fitscreen(img._width,img._height,img._depth,128,-85,
true);
44177 if (w>max_width) max_width = w;
44180 disp.
assign(cimg_fitscreen(max_width,sum_height,1),title?title:0,1);
44183 }
else if (title) disp.
set_title(
"%s",title);
44189 const unsigned int dw = disp._width, dh = disp._height;
44190 if (!is_first_call)
44191 disp.
resize(cimg_fitscreen(_data[0]._width,_data[0]._height,_data[0]._depth),
false).
44192 set_title(
"%s (%ux%ux%ux%u)",dtitle.data(),_data[0]._width,_data[0]._height,_data[0]._depth,_data[0]._spectrum);
44193 _data[0]._display(disp,0,
false,XYZ,!is_first_call);
44194 if (disp.
key()) is_exit =
true;
44195 disp.
resize(cimg_fitscreen(dw,dh,1),
false).
set_title(
"%s",dtitle.data());
44197 bool disp_resize = !is_first_call;
44198 while (!disp.
is_closed() && !is_exit) {
44199 const CImg<intT> s = _get_select(disp,0,
true,axis,align,orig,disp_resize,!is_first_call,
true);
44200 disp_resize =
true;
44204 }
else if (disp.
wheel()) {
44205 const int wheel = disp.
wheel();
44207 if (!is_first_call && wheel<0)
break;
44208 if (wheel>0 && _width>=4) {
44211 ind0 = (
unsigned int)
cimg::max(0,s[0] - (
int)delta),
44213 if ((ind0!=0 || ind1!=_width-1) && ind1 - ind0>=3) get_shared_images(ind0,ind1)._display(disp,0,
false,axis,align,XYZ,orig + ind0,
false,is_exit);
44215 }
else if (s[0]!=0 || s[1]!=
width()-1) get_shared_images(s[0],s[1])._display(disp,0,
false,axis,align,XYZ,orig+s[0],
false,is_exit);
44229 "save(): Specified filename is (null).",
44230 cimglist_instance);
44233 char nfilename[1024] = { 0 };
44235 #ifdef cimglist_save_plugin
44236 cimglist_save_plugin(fn);
44238 #ifdef cimglist_save_plugin1
44239 cimglist_save_plugin1(fn);
44241 #ifdef cimglist_save_plugin2
44242 cimglist_save_plugin2(fn);
44244 #ifdef cimglist_save_plugin3
44245 cimglist_save_plugin3(fn);
44247 #ifdef cimglist_save_plugin4
44248 cimglist_save_plugin4(fn);
44250 #ifdef cimglist_save_plugin5
44251 cimglist_save_plugin5(fn);
44253 #ifdef cimglist_save_plugin6
44254 cimglist_save_plugin6(fn);
44256 #ifdef cimglist_save_plugin7
44257 cimglist_save_plugin7(fn);
44259 #ifdef cimglist_save_plugin8
44260 cimglist_save_plugin8(fn);
44286 #ifdef cimg_use_tiff
44291 else {
if (_width==1) _data[0].save(fn,-1);
else cimglist_for(*
this,l) _data[l].save(fn,l); }
44303 #ifdef cimg_use_tiff
44339 char command[1024] = { 0 }, filetmp[512] = { 0 }, filetmp2[512] = { 0 };
44341 std::FILE *file = 0;
44343 #ifdef cimg_use_png
44344 #define _cimg_save_gif_ext "png"
44346 #define _cimg_save_gif_ext "ppm"
44350 cimg_snprintf(filetmp,
sizeof(filetmp),
"%s%c%s",
cimg::temporary_path(),cimg_file_separator,cimg::filenamerand());
44351 cimg_snprintf(filetmp2,
sizeof(filetmp2),
"%s_000001." _cimg_save_gif_ext,filetmp);
44352 if ((file=std::fopen(filetmp2,
"rb"))!=0)
cimg::fclose(file);
44354 cimglist_for(*
this,l) {
44355 cimg_snprintf(filetmp2,
sizeof(filetmp2),
"%s_%.6u." _cimg_save_gif_ext,filetmp,l+1);
44357 if (_data[l]._depth>1 || _data[l]._spectrum!=3) _data[l].get_resize(-100,-100,1,3).save(filetmp2);
44358 else _data[l].save(filetmp2);
44362 cimg_snprintf(command,
sizeof(command),
"%s -delay 1x%u -loop %u",
44365 cimg_snprintf(command,
sizeof(command),
"\"%s\" >/dev/null 2>&1",
44369 cimg_snprintf(command,
sizeof(command),
"\"%s -delay 1x%u -loop %u",
44372 cimg_snprintf(command,
sizeof(command),
"\"%s\"\" >NUL 2>&1",
44377 cimg_for(_command,p,
char)
if (!*p) *p =
' ';
44378 _command.
back() = 0;
44380 file = std::fopen(filename,
"rb");
44383 "save_gif_external(): Failed to save file '%s' with external command 'convert'.",
44387 cimglist_for_in(*
this,1,filenames._width-2,l) std::remove(filenames[l]);
44401 "save_ffmpeg(): Specified filename is (null).",
44402 cimglist_instance);
44405 "save_ffmpeg(): Empty instance, for file '%s'.",
44410 "save_ffmpeg(): Invalid specified framerate 0, for file '%s'.",
44414 cimglist_for(*
this,l)
if (!_data[l].
is_sameXYZ(_data[0]))
44416 "save_ffmpeg(): Invalid instance dimensions, for file '%s'.",
44420 #ifndef cimg_use_ffmpeg
44423 avcodec_register_all();
44426 frame_dimx = _data[0].width(),
44427 frame_dimy = _data[0].height(),
44428 frame_dimv = _data[0].spectrum();
44429 if (frame_dimv!=1 && frame_dimv!=3)
44431 "save_ffmpeg(): Image[0] (%u,%u,%u,%u,%p) has not 1 or 3 channels, for file '%s'.",
44433 _data[0]._width,_data[0]._height,_data[0]._depth,_data[0]._spectrum,_data,filename);
44435 PixelFormat dest_pxl_fmt = PIX_FMT_YUV420P;
44436 PixelFormat src_pxl_fmt = (frame_dimv==3)?PIX_FMT_RGB24:PIX_FMT_GRAY8;
44438 int sws_flags = SWS_FAST_BILINEAR;
44439 AVOutputFormat *fmt = 0;
44440 #if defined(AV_VERSION_INT)
44441 #if LIBAVFORMAT_VERSION_INT<AV_VERSION_INT(52,45,0)
44442 fmt = guess_format(0,filename,0);
44443 if (!fmt) fmt = guess_format(
"mpeg",0,0);
44445 fmt = av_guess_format(0,filename,0);
44446 if (!fmt) fmt = av_guess_format(
"mpeg",0,0);
44449 fmt = guess_format(0,filename,0);
44450 if (!fmt) fmt = guess_format(
"mpeg",0,0);
44455 "save_ffmpeg(): Unable to determine codec for file '%s'.",
44459 AVFormatContext *oc = 0;
44460 #if defined(AV_VERSION_INT)
44461 #if LIBAVFORMAT_VERSION_INT<AV_VERSION_INT(52,36,0)
44462 oc = av_alloc_format_context();
44464 oc = avformat_alloc_context();
44467 oc = av_alloc_format_context();
44471 "save_ffmpeg(): Failed to allocate FFMPEG structure for format context, for file '%s'.",
44475 AVCodec *codec = 0;
44476 AVFrame *picture = 0;
44477 AVFrame *tmp_pict = 0;
44479 std::sprintf(oc->filename,
"%s",filename);
44482 int stream_index = 0;
44483 AVStream *video_str = 0;
44484 if (fmt->video_codec!=CODEC_ID_NONE) {
44485 video_str = av_new_stream(oc,stream_index);
44489 "save_ffmpeg(): Failed to allocate FFMPEG structure for video stream, for file '%s'.",
44496 "save_ffmpeg(): Failed to identify proper codec, for file '%s'.",
44501 AVCodecContext *c = video_str->codec;
44502 c->codec_id = fmt->video_codec;
44503 c->codec_type = CODEC_TYPE_VIDEO;
44504 c->bit_rate = 1024*bitrate;
44505 c->width = frame_dimx;
44506 c->height = frame_dimy;
44507 c->time_base.num = 1;
44508 c->time_base.den = fps;
44510 c->pix_fmt = dest_pxl_fmt;
44511 if (c->codec_id==CODEC_ID_MPEG2VIDEO) c->max_b_frames = 2;
44512 if (c->codec_id==CODEC_ID_MPEG1VIDEO) c->mb_decision = 2;
44514 if (av_set_parameters(oc,0)<0) {
44517 "save_ffmpeg(): Invalid parameters set for avcodec, for file '%s'.",
44523 codec = avcodec_find_encoder(c->codec_id);
44527 "save_ffmpeg(): No valid codec found for file '%s'.",
44531 if (avcodec_open(c,codec)<0)
44533 "save_ffmpeg(): Failed to open codec for file '%s'.",
44537 tmp_pict = avcodec_alloc_frame();
44539 avcodec_close(video_str->codec);
44542 "save_ffmpeg(): Failed to allocate memory for file '%s'.",
44546 tmp_pict->linesize[0] = (src_pxl_fmt==PIX_FMT_RGB24)?3*frame_dimx:frame_dimx;
44547 tmp_pict->type = FF_BUFFER_TYPE_USER;
44548 int tmp_size = avpicture_get_size(src_pxl_fmt,frame_dimx,frame_dimy);
44549 uint8_t *tmp_buffer = (uint8_t*)av_malloc(tmp_size);
44552 avcodec_close(video_str->codec);
44555 "save_ffmpeg(): Failed to allocate memory for file '%s'.",
44561 avpicture_fill((AVPicture*)tmp_pict,tmp_buffer,src_pxl_fmt,frame_dimx,frame_dimy);
44562 picture = avcodec_alloc_frame();
44564 av_free(tmp_pict->data[0]);
44566 avcodec_close(video_str->codec);
44569 "save_ffmpeg(): Failed to allocate memory for file '%s'.",
44574 int size = avpicture_get_size(c->pix_fmt,frame_dimx,frame_dimy);
44575 uint8_t *buffer = (uint8_t*)av_malloc(size);
44578 av_free(tmp_pict->data[0]);
44580 avcodec_close(video_str->codec);
44583 "save_ffmpeg(): Failed to allocate memory for file '%s'.",
44589 avpicture_fill((AVPicture*)picture,buffer,c->pix_fmt,frame_dimx,frame_dimy);
44592 if (!(fmt->flags&AVFMT_NOFILE)) {
44593 if (url_fopen(&oc->pb,filename,URL_WRONLY)<0)
44595 "save_ffmpeg(): Failed to open file '%s'.",
44600 if (av_write_header(oc)<0)
44602 "save_ffmpeg(): Failed to write header in file '%s'.",
44606 SwsContext *img_convert_context = 0;
44607 img_convert_context = sws_getContext(frame_dimx,frame_dimy,src_pxl_fmt,
44608 c->width,c->height,c->pix_fmt,sws_flags,0,0,0);
44609 if (!img_convert_context) {
44611 av_free(picture->data);
44613 av_free(tmp_pict->data[0]);
44615 avcodec_close(video_str->codec);
44618 "save_ffmpeg(): Failed to get conversion context for file '%s'.",
44622 int ret = 0, out_size;
44623 uint8_t *video_outbuf = 0;
44624 int video_outbuf_size = 1000000;
44625 video_outbuf = (uint8_t*)av_malloc(video_outbuf_size);
44626 if (!video_outbuf) {
44628 av_free(picture->data);
44630 av_free(tmp_pict->data[0]);
44632 avcodec_close(video_str->codec);
44635 "save_ffmpeg(): Failed to allocate memory, for file '%s'.",
44641 cimglist_for(*
this,i) {
44642 CImg<uint8_t> currentIm = _data[i], red, green, blue, gray;
44643 if (src_pxl_fmt==PIX_FMT_RGB24) {
44644 red = currentIm.get_shared_channel(0);
44645 green = currentIm.get_shared_channel(1);
44646 blue = currentIm.get_shared_channel(2);
44647 cimg_forXY(currentIm,X,Y) {
44648 tmp_pict->data[0][Y*tmp_pict->linesize[0] + 3*X] = red(X,Y);
44649 tmp_pict->data[0][Y*tmp_pict->linesize[0] + 3*X + 1] = green(X,Y);
44650 tmp_pict->data[0][Y*tmp_pict->linesize[0] + 3*X + 2] = blue(X,Y);
44653 gray = currentIm.get_shared_channel(0);
44654 cimg_forXY(currentIm,X,Y) tmp_pict->data[0][Y*tmp_pict->linesize[0] + X] = gray(X,Y);
44656 if (!video_str)
break;
44657 if (sws_scale(img_convert_context,tmp_pict->data,tmp_pict->linesize,0,c->height,picture->data,picture->linesize)<0)
break;
44658 out_size = avcodec_encode_video(c,video_outbuf,video_outbuf_size,picture);
44661 av_init_packet(&pkt);
44662 pkt.pts = av_rescale_q(c->coded_frame->pts,c->time_base,video_str->time_base);
44663 if (c->coded_frame->key_frame) pkt.flags|=PKT_FLAG_KEY;
44664 pkt.stream_index = video_str->index;
44665 pkt.data = video_outbuf;
44666 pkt.size = out_size;
44667 ret = av_write_frame(oc,&pkt);
44668 }
else if (out_size<0)
break;
44674 avcodec_close(video_str->codec);
44675 av_free(picture->data[0]);
44677 av_free(tmp_pict->data[0]);
44680 if (av_write_trailer(oc)<0)
44682 "save_ffmpeg(): Failed to write trailer for file '%s'.",
44686 av_freep(&oc->streams[stream_index]->codec);
44687 av_freep(&oc->streams[stream_index]);
44688 if (!(fmt->flags&AVFMT_NOFILE)) {
44697 av_free(video_outbuf);
44702 const CImgList<T>& _save_yuv(std::FILE *
const file,
const char *
const filename,
const bool is_rgb)
const {
44703 if (!file && !filename)
44705 "save_yuv(): Specified filename is (null).",
44706 cimglist_instance);
44709 "save_yuv(): Empty instance, for file '%s'.",
44711 filename?filename:
"(FILE*)");
44713 if ((*
this)[0].
width()%2 || (*
this)[0].
height()%2)
44715 "save_yuv(): Invalid odd instance dimensions (%u,%u) for file '%s'.",
44718 filename?filename:
"(FILE*)");
44720 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"wb");
44721 cimglist_for(*
this,l) {
44723 if (is_rgb) YCbCr.RGBtoYCbCr();
44724 cimg::fwrite(YCbCr._data,(
unsigned long)YCbCr._width*YCbCr._height,nfile);
44725 cimg::fwrite(YCbCr.get_resize(YCbCr._width/2, YCbCr._height/2,1,3,3).data(0,0,0,1),
44726 (
unsigned long)YCbCr._width*YCbCr._height/2,nfile);
44738 return _save_yuv(0,filename,is_rgb);
44747 return _save_yuv(file,0,is_rgb);
44750 const CImgList<T>& _save_cimg(std::FILE *
const file,
const char *
const filename,
const bool is_compressed)
const {
44751 if (!file && !filename)
44753 "save_cimg(): Specified filename is (null).",
44754 cimglist_instance);
44755 #ifndef cimg_use_zlib
44758 "save_cimg(): Unable to save compressed data in file '%s' unless zlib is enabled, saving them uncompressed.",
44760 filename?filename:
"(FILE*)");
44762 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"wb");
44764 if (std::strstr(ptype,
"unsigned")==ptype) std::fprintf(nfile,
"%u unsigned_%s %s_endian\n",_width,ptype+9,etype);
44765 else std::fprintf(nfile,
"%u %s %s_endian\n",_width,ptype,etype);
44766 cimglist_for(*
this,l) {
44767 const CImg<T>& img = _data[l];
44768 std::fprintf(nfile,
"%u %u %u %u",img._width,img._height,img._depth,img._spectrum);
44773 bool failed_to_compress =
true;
44774 if (is_compressed) {
44775 #ifdef cimg_use_zlib
44776 const unsigned long siz =
sizeof(T)*ref.size();
44777 unsigned long csiz = siz + siz/100 + 16;
44778 Bytef *
const cbuf =
new Bytef[csiz];
44779 if (compress(cbuf,&csiz,(Bytef*)ref._data,siz))
44781 "save_cimg(): Failed to save compressed data for file '%s', saving them uncompressed.",
44783 filename?filename:
"(FILE*)");
44785 std::fprintf(nfile,
" #%lu\n",csiz);
44788 failed_to_compress =
false;
44792 if (failed_to_compress) {
44793 std::fputc(
'\n',nfile);
44796 }
else std::fputc(
'\n',nfile);
44808 return _save_cimg(0,filename,is_compressed);
44817 return _save_cimg(file,0,is_compressed);
44820 const CImgList<T>& _save_cimg(std::FILE *
const file,
const char *
const filename,
44821 const unsigned int n0,
44822 const unsigned int x0,
const unsigned int y0,
44823 const unsigned int z0,
const unsigned int c0)
const {
44824 #define _cimg_save_cimg_case(Ts,Tss) \
44825 if (!saved && !cimg::strcasecmp(Ts,str_pixeltype)) { \
44826 for (unsigned int l = 0; l<lmax; ++l) { \
44827 j = 0; while((i=std::fgetc(nfile))!='\n') tmp[j++]=(char)i; tmp[j] = 0; \
44828 W = H = D = C = 0; \
44829 if (std::sscanf(tmp,"%u %u %u %u",&W,&H,&D,&C)!=4) \
44830 throw CImgIOException(_cimglist_instance \
44831 "save_cimg(): Invalid size (%u,%u,%u,%u) of image[%u], for file '%s'.", \
44832 cimglist_instance, \
44833 W,H,D,C,l,filename?filename:"(FILE*)"); \
44835 if (l<n0 || x0>=W || y0>=H || z0>=D || c0>=D) std::fseek(nfile,W*H*D*C*sizeof(Tss),SEEK_CUR); \
44837 const CImg<T>& img = (*this)[l - n0]; \
44838 const T *ptrs = img._data; \
44839 const unsigned int \
44840 x1 = x0 + img._width - 1, \
44841 y1 = y0 + img._height - 1, \
44842 z1 = z0 + img._depth - 1, \
44843 c1 = c0 + img._spectrum - 1, \
44844 nx1 = x1>=W?W-1:x1, \
44845 ny1 = y1>=H?H-1:y1, \
44846 nz1 = z1>=D?D-1:z1, \
44847 nc1 = c1>=C?C-1:c1; \
44848 CImg<Tss> raw(1+nx1-x0); \
44849 const unsigned int skipvb = c0*W*H*D*sizeof(Tss); \
44850 if (skipvb) std::fseek(nfile,skipvb,SEEK_CUR); \
44851 for (unsigned int v = 1 + nc1 - c0; v; --v) { \
44852 const unsigned int skipzb = z0*W*H*sizeof(Tss); \
44853 if (skipzb) std::fseek(nfile,skipzb,SEEK_CUR); \
44854 for (unsigned int z = 1 + nz1 - z0; z; --z) { \
44855 const unsigned int skipyb = y0*W*sizeof(Tss); \
44856 if (skipyb) std::fseek(nfile,skipyb,SEEK_CUR); \
44857 for (unsigned int y = 1 + ny1 - y0; y; --y) { \
44858 const unsigned int skipxb = x0*sizeof(Tss); \
44859 if (skipxb) std::fseek(nfile,skipxb,SEEK_CUR); \
44860 raw.assign(ptrs, raw._width); \
44861 ptrs+=img._width; \
44862 if (endian) cimg::invert_endianness(raw._data,raw._width); \
44863 cimg::fwrite(raw._data,raw._width,nfile); \
44864 const unsigned int skipxe = (W - 1 - nx1)*sizeof(Tss); \
44865 if (skipxe) std::fseek(nfile,skipxe,SEEK_CUR); \
44867 const unsigned int skipye = (H - 1 - ny1)*W*sizeof(Tss); \
44868 if (skipye) std::fseek(nfile,skipye,SEEK_CUR); \
44870 const unsigned int skipze = (D - 1 - nz1)*W*H*sizeof(Tss); \
44871 if (skipze) std::fseek(nfile,skipze,SEEK_CUR); \
44873 const unsigned int skipve = (C - 1 - nc1)*W*H*D*sizeof(Tss); \
44874 if (skipve) std::fseek(nfile,skipve,SEEK_CUR); \
44881 if (!file && !filename)
44883 "save_cimg(): Specified filename is (null).",
44884 cimglist_instance);
44887 "save_cimg(): Empty instance, for file '%s'.",
44889 filename?filename:
"(FILE*)");
44891 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"rb+");
44893 char tmp[256] = { 0 }, str_pixeltype[256] = { 0 }, str_endian[256] = { 0 };
44894 unsigned int j, err, N, W, H, D, C;
44896 j = 0;
while((i=std::fgetc(nfile))!=
'\n' && i!=EOF && j<256) tmp[j++] = (char)i; tmp[j] = 0;
44897 err = std::sscanf(tmp,
"%u%*c%255[A-Za-z_]%*c%255[sA-Za-z_ ]",&N,str_pixeltype,str_endian);
44900 throw CImgIOException(_cimglist_instance
44901 "save_cimg(): CImg header not found in file '%s'.",
44903 filename?filename:
"(FILE*)");
44907 const unsigned int lmax =
cimg::min(N,n0+_width);
44908 _cimg_save_cimg_case(
"bool",
bool);
44909 _cimg_save_cimg_case(
"unsigned_char",
unsigned char);
44910 _cimg_save_cimg_case(
"uchar",
unsigned char);
44911 _cimg_save_cimg_case(
"char",
char);
44912 _cimg_save_cimg_case(
"unsigned_short",
unsigned short);
44913 _cimg_save_cimg_case(
"ushort",
unsigned short);
44914 _cimg_save_cimg_case(
"short",
short);
44915 _cimg_save_cimg_case(
"unsigned_int",
unsigned int);
44916 _cimg_save_cimg_case(
"uint",
unsigned int);
44917 _cimg_save_cimg_case(
"int",
int);
44918 _cimg_save_cimg_case(
"unsigned_long",
unsigned long);
44919 _cimg_save_cimg_case(
"ulong",
unsigned long);
44920 _cimg_save_cimg_case(
"long",
long);
44921 _cimg_save_cimg_case(
"float",
float);
44922 _cimg_save_cimg_case(
"double",
double);
44925 throw CImgIOException(_cimglist_instance
44926 "save_cimg(): Unsupported data type '%s' for file '%s'.",
44928 filename?filename:
"(FILE*)",str_pixeltype);
44944 const unsigned int n0,
44945 const unsigned int x0,
const unsigned int y0,
44946 const unsigned int z0,
const unsigned int c0)
const {
44947 return _save_cimg(0,filename,n0,x0,y0,z0,c0);
44960 const unsigned int n0,
44961 const unsigned int x0,
const unsigned int y0,
44962 const unsigned int z0,
const unsigned int c0)
const {
44963 return _save_cimg(file,0,n0,x0,y0,z0,c0);
44966 static void _save_empty_cimg(std::FILE *
const file,
const char *
const filename,
44967 const unsigned int nb,
44968 const unsigned int dx,
const unsigned int dy,
44969 const unsigned int dz,
const unsigned int dc) {
44970 std::FILE *
const nfile = file?file:
cimg::fopen(filename,
"wb");
44971 const unsigned long siz = (
unsigned long)dx*dy*dz*dc*
sizeof(T);
44972 std::fprintf(nfile,
"%u %s\n",nb,
pixel_type());
44973 for (
unsigned int i=nb; i; --i) {
44974 std::fprintf(nfile,
"%u %u %u %u\n",dx,dy,dz,dc);
44975 for (
unsigned long off=siz; off; --off) std::fputc(0,nfile);
44990 const unsigned int nb,
44991 const unsigned int dx,
const unsigned int dy=1,
44992 const unsigned int dz=1,
const unsigned int dc=1) {
44993 return _save_empty_cimg(0,filename,nb,dx,dy,dz,dc);
45006 const unsigned int nb,
45007 const unsigned int dx,
const unsigned int dy=1,
45008 const unsigned int dz=1,
const unsigned int dc=1) {
45009 return _save_empty_cimg(file,0,nb,dx,dy,dz,dc);
45020 "save_tiff(): Specified filename is (null).",
45021 cimglist_instance);
45024 "save_tiff(): Empty instance, for file '%s'.",
45027 #ifndef cimg_use_tiff
45028 if (_width==1) _data[0].save_tiff(filename,compression_type);
45029 else cimglist_for(*
this,l) {
45030 char nfilename[1024] = { 0 };
45032 _data[l].save_tiff(nfilename,compression_type);
45035 TIFF *tif = TIFFOpen(filename,
"w");
45037 for (
unsigned int dir = 0, l = 0; l<_width; ++l) {
45038 const CImg<T>& img = (*this)[l];
45040 if (img._depth==1) img._save_tiff(tif,dir++,compression_type);
45041 else cimg_forZ(img,z) img.get_slice(z)._save_tiff(tif,dir++,compression_type);
45047 "save_tiff(): Failed to open stream for file '%s'.",
45062 "save_gzip_external(): Specified filename is (null).",
45063 cimglist_instance);
45065 char command[1024] = { 0 }, filetmp[512] = { 0 }, body[512] = { 0 };
45072 if (*ext2) cimg_snprintf(filetmp,
sizeof(filetmp),
"%s%c%s.%s",
cimg::temporary_path(),cimg_file_separator,cimg::filenamerand(),ext2);
45073 else cimg_snprintf(filetmp,
sizeof(filetmp),
"%s%c%s.cimg",
cimg::temporary_path(),cimg_file_separator,cimg::filenamerand());
45075 if (*ext) cimg_snprintf(filetmp,
sizeof(filetmp),
"%s%c%s.%s",
cimg::temporary_path(),cimg_file_separator,cimg::filenamerand(),ext);
45076 else cimg_snprintf(filetmp,
sizeof(filetmp),
"%s%c%s.cimg",
cimg::temporary_path(),cimg_file_separator,cimg::filenamerand());
45078 if ((file=std::fopen(filetmp,
"rb"))!=0)
cimg::fclose(file);
45081 if (is_saveable(body)) {
45083 cimg_snprintf(command,
sizeof(command),
"%s -c %s > \"%s\"",
cimg::gzip_path(),filetmp,filename);
45085 file = std::fopen(filename,
"rb");
45088 "save_gzip_external(): Failed to save file '%s' with external command 'gzip'.",
45092 std::remove(filetmp);
45094 char nfilename[1024] = { 0 };
45095 cimglist_for(*
this,l) {
45097 if (*ext) std::sprintf(nfilename + std::strlen(nfilename),
".%s",ext);
45098 _data[l].save_gzip_external(nfilename);
45112 const unsigned int fps=25,
const unsigned int bitrate=2048)
const {
45115 "save_ffmpeg_external(): Specified filename is (null).",
45116 cimglist_instance);
45119 "save_ffmpeg_external(): Empty instance, for file '%s'.",
45124 *
const _codec = codec?codec:!
cimg::strcasecmp(ext,
"flv")?
"flv":
"mpeg2video";
45126 char command[1024] = { 0 }, filetmp[512] = { 0 }, filetmp2[512] = { 0 };
45128 std::FILE *file = 0;
45129 cimglist_for(*
this,l)
if (!_data[l].
is_sameXYZ(_data[0]))
45131 "save_ffmpeg_external(): Invalid instance dimensions for file '%s'.",
45135 cimg_snprintf(filetmp,
sizeof(filetmp),
"%s%c%s",
cimg::temporary_path(),cimg_file_separator,cimg::filenamerand());
45136 cimg_snprintf(filetmp2,
sizeof(filetmp2),
"%s_000001.ppm",filetmp);
45137 if ((file=std::fopen(filetmp2,
"rb"))!=0)
cimg::fclose(file);
45139 cimglist_for(*
this,l) {
45140 cimg_snprintf(filetmp2,
sizeof(filetmp2),
"%s_%.6u.ppm",filetmp,l+1);
45142 if (_data[l]._depth>1 || _data[l]._spectrum!=3) _data[l].get_resize(-100,-100,1,3).save_pnm(filetmp2);
45143 else _data[l].save_pnm(filetmp2);
45146 cimg_snprintf(command,
sizeof(command),
"%s -i %s_%%6d.ppm -vcodec %s -b %uk -r %u -y \"%s\" >/dev/null 2>&1",
45149 cimg_snprintf(command,
sizeof(command),
"\"%s -i %s_%%6d.ppm -vcodec %s -b %uk -r %u -y \"%s\"\" >NUL 2>&1",
45153 file = std::fopen(filename,
"rb");
45156 "save_ffmpeg_external(): Failed to save file '%s' with external command 'ffmpeg'.",
45160 cimglist_for(*
this,l) std::remove(filenames[l]);
45175 return get_crop_font().
move_to(*
this);
45183 cimglist_for(*
this,l) {
45184 const CImg<T>& letter = (*this)[l];
45185 int xmin = letter._width, xmax = 0;
45186 cimg_forXY(letter,x,y)
if (letter(x,y)) {
if (x<xmin) xmin = x;
if (x>xmax) xmax = x; }
45187 if (xmin>xmax)
CImg<T>(letter._width,letter._height,1,letter._spectrum,0).
move_to(res);
45188 else letter.get_crop(xmin,0,xmax,letter._height-1).move_to(res);
45190 res[
' '].resize(res[
'f']._width,-100,-100,-100,0);
45191 if (
' '+256<res.size()) res[
' '+256].
resize(res[
'f']._width,-100,-100,-100,0);
45201 static const CImgList<T>&
font(
const unsigned int font_height,
const bool is_variable_width=
true) {
45203 #define _cimg_font(sx,sy) \
45204 if (!is_variable_width && (!font || font[0]._height!=sy)) font = _font(cimg::font##sx##x##sy,sx,sy,false); \
45205 if (is_variable_width && (!vfont || vfont[0]._height!=sy)) vfont = _font(cimg::font##sx##x##sy,sx,sy,true); \
45206 if (font_height==sy) return is_variable_width?vfont:font; \
45207 if (is_variable_width) { \
45208 if (cvfont && font_height==cvfont[0]._height) return cvfont; \
45210 cimglist_for(cvfont,l) \
45211 cvfont[l].resize(cimg::max(1U,cvfont[l]._width*font_height/cvfont[l]._height),font_height,-100,-100, \
45212 cvfont[0]._height>font_height?2:5); \
45215 if (cfont && font_height==cfont[0]._height) return cfont; \
45217 cimglist_for(cfont,l) \
45218 cfont[l].resize(cimg::max(1U,cfont[l]._width*font_height/cfont[l]._height),font_height,-100,-100, \
45219 cfont[0]._height>font_height?2:5); \
45225 if (font_height<=13) { _cimg_font(10,13); }
45226 if (font_height<=28) { _cimg_font(12,24); }
45227 if (font_height<=32) { _cimg_font(16,32); }
45231 static CImgList<T> _font(
const unsigned int *
const font,
const unsigned int w,
const unsigned int h,
const bool is_variable_width) {
45233 const unsigned int *ptr = font;
45234 unsigned int m = 0, val = 0;
45235 for (
unsigned int y = 0; y<h; ++y)
45236 for (
unsigned int x = 0; x<256*w; ++x) {
45237 m>>=1;
if (!m) { m = 0x80000000; val = *(ptr++); }
45238 CImg<T>& img = res[x/w];
45239 unsigned int xm = x%w;
45240 img(xm,y) = (T)((val&m)?1:0);
45242 if (is_variable_width) res.crop_font();
45243 return res.insert(res);
45253 if (_width==1) insert(1);
45256 "FFT(): Instance has more than 2 images",
45257 cimglist_instance);
45274 if (_width==1) insert(1);
45277 "FFT(): Instance has more than 2 images",
45278 cimglist_instance);
45293 cimglist_for(*
this,l) {
45295 switch (p.size()) {
45296 case 2:
case 3:
cimg::swap(p[0],p[1]);
break;
45297 case 6:
cimg::swap(p[0],p[1],p[2],p[4],p[3],p[5]);
break;
45298 case 9:
cimg::swap(p[0],p[1],p[3],p[5],p[4],p[6]);
break;
45299 case 4:
cimg::swap(p[0],p[1],p[2],p[3]);
break;
45300 case 12:
cimg::swap(p[0],p[1],p[2],p[3],p[4],p[6],p[5],p[7],p[8],p[10],p[9],p[11]);
break;
45342 template<
typename t>
45343 inline int dialog(
const char *
const title,
const char *
const msg,
45344 const char *
const button1_label,
const char *
const button2_label,
45345 const char *
const button3_label,
const char *
const button4_label,
45346 const char *
const button5_label,
const char *
const button6_label,
45347 const CImg<t>& logo,
const bool is_centered =
false) {
45348 #if cimg_display==0
45349 cimg::unused(title,msg,button1_label,button2_label,button3_label,button4_label,button5_label,button6_label,logo._data,is_centered);
45352 const unsigned char
45353 black[] = { 0,0,0 }, white[] = { 255,255,255 }, gray[] = { 200,200,200 }, gray2[] = { 150,150,150 };
45364 if (!buttons._width)
45366 cimglist_for(buttons,l) buttons[l].resize(-100,-100,1,3);
45368 unsigned int bw = 0, bh = 0;
45369 cimglist_for(buttons,l) { bw =
cimg::max(bw,buttons[l]._width); bh =
cimg::max(bh,buttons[l]._height); }
45371 if (bw<64) bw = 64;
45372 if (bw>128) bw = 128;
45373 if (bh<24) bh = 24;
45374 if (bh>48) bh = 48;
45377 button.draw_rectangle(0,0,bw-1,bh-1,gray);
45378 button.draw_line(0,0,bw-1,0,white).draw_line(0,bh-1,0,0,white);
45379 button.draw_line(bw-1,0,bw-1,bh-1,black).draw_line(bw-1,bh-1,0,bh-1,black);
45380 button.draw_line(1,bh-2,bw-2,bh-2,gray2).draw_line(bw-2,bh-2,bw-2,1,gray2);
45382 sbutton.draw_rectangle(0,0,bw-1,bh-1,gray);
45383 sbutton.draw_line(0,0,bw-1,0,black).draw_line(bw-1,0,bw-1,bh-1,black);
45384 sbutton.draw_line(bw-1,bh-1,0,bh-1,black).draw_line(0,bh-1,0,0,black);
45385 sbutton.draw_line(1,1,bw-2,1,white).draw_line(1,bh-2,1,1,white);
45386 sbutton.draw_line(bw-2,1,bw-2,bh-2,black).draw_line(bw-2,bh-2,1,bh-2,black);
45387 sbutton.draw_line(2,bh-3,bw-3,bh-3,gray2).draw_line(bw-3,bh-3,bw-3,2,gray2);
45388 sbutton.draw_line(4,4,bw-5,4,black,1,0xAAAAAAAA,
true).draw_line(bw-5,4,bw-5,bh-5,black,1,0xAAAAAAAA,
false);
45389 sbutton.draw_line(bw-5,bh-5,4,bh-5,black,1,0xAAAAAAAA,
false).draw_line(4,bh-5,4,4,black,1,0xAAAAAAAA,
false);
45391 cbutton.draw_rectangle(0,0,bw-1,bh-1,black).draw_rectangle(1,1,bw-2,bh-2,gray2).draw_rectangle(2,2,bw-3,bh-3,gray);
45392 cbutton.draw_line(4,4,bw-5,4,black,1,0xAAAAAAAA,
true).draw_line(bw-5,4,bw-5,bh-5,black,1,0xAAAAAAAA,
false);
45393 cbutton.draw_line(bw-5,bh-5,4,bh-5,black,1,0xAAAAAAAA,
false).draw_line(4,bh-5,4,4,black,1,0xAAAAAAAA,
false);
45395 cimglist_for(buttons,ll) {
45405 if (msg)
CImg<unsigned char>().
draw_text(0,0,
"%s",black,gray,1,13,msg).resize(-100,-100,1,3).move_to(canvas);
45407 bwall = (buttons._width-1)*(12+bw) + bw,
45408 w =
cimg::max(196U,36+logo._width+canvas._width,24+bwall),
45409 h =
cimg::max(96U,36+canvas._height+bh,36+logo._height+bh),
45410 lx = 12 + (canvas._data?0:((w-24-logo._width)/2)),
45411 ly = (h-12-bh-logo._height)/2,
45412 tx = lx+logo._width+12,
45413 ty = (h-12-bh-canvas._height)/2,
45420 draw_line(0,0,w-1,0,white).draw_line(0,h-1,0,0,white).
45421 draw_line(w-1,0,w-1,h-1,black).draw_line(w-1,h-1,0,h-1,black).
45426 draw_line(0,0,w-1,0,white).draw_line(0,h-1,0,0,white).
45427 draw_line(w-1,0,w-1,h-1,black).draw_line(w-1,h-1,0,h-1,black);
45428 if (logo._data) canvas.draw_image(lx,ly,logo);
45430 unsigned int xbuttons[6] = { 0 };
45431 cimglist_for(buttons,lll) { xbuttons[lll] = bx+(bw+12)*lll; canvas.draw_image(xbuttons[lll],by,buttons[lll]); }
45434 CImgDisplay disp(canvas,title?title:
" ",0,
false,is_centered?
true:
false);
45437 bool stopflag =
false, refresh =
false;
45438 int oselected = -1, oclicked = -1, selected = -1, clicked = -1;
45439 while (!disp.
is_closed() && !stopflag) {
45444 else canvas.display(disp);
45452 oclicked = clicked;
45454 cimglist_for(buttons,l)
45456 disp.
mouse_x()>=(int)xbuttons[l] && disp.
mouse_x()<(int)(xbuttons[l]+bw)) {
45457 clicked = selected = l;
45460 if (clicked!=oclicked) refresh =
true;
45461 }
else if (clicked>=0) stopflag =
true;
45464 oselected = selected;
45465 switch (disp.
key()) {
45466 case cimg::keyESC : selected=-1; stopflag=
true;
break;
45467 case cimg::keyENTER :
if (selected<0) selected = 0; stopflag =
true;
break;
45472 case cimg::keyARROWUP : selected = (selected+buttons._width-1)%buttons._width;
break;
45475 if (selected!=oselected) refresh =
true;
45478 if (!disp) selected = -1;
45484 inline int dialog(
const char *
const title,
const char *
const msg,
45485 const char *
const button1_label,
const char *
const button2_label,
const char *
const button3_label,
45486 const char *
const button4_label,
const char *
const button5_label,
const char *
const button6_label,
45487 const bool is_centered) {
45488 return dialog(title,msg,button1_label,button2_label,button3_label,button4_label,button5_label,button6_label,
45508 inline double eval(
const char *
const expression,
const double x,
const double y,
const double z,
const double c) {
45510 return empty.eval(expression,x,y,z,c);
45520 namespace cil = cimg_library_suffixed;
45522 #ifdef _cimg_redefine_False
45525 #ifdef _cimg_redefine_True
45528 #ifdef _cimg_redefine_None
45531 #ifdef _cimg_redefine_min
45532 #define min(a,b) (((a)<(b))?(a):(b))
45534 #ifdef _cimg_redefine_max
45535 #define max(a,b) (((a)>(b))?(a):(b))
45537 #ifdef _cimg_redefine_PI
45538 #define PI 3.141592653589793238462643383